home *** CD-ROM | disk | FTP | other *** search
/ Aminet 41 / Aminet 41 (2001)(Schatztruhe)[!][Feb 2001].iso / Aminet / dev / c / libmpeg_src.lha / video.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-09-25  |  89.2 KB  |  3,462 lines

  1. /*
  2.  * Copyright (c) 1992 The Regents of the University of California.
  3.  * All rights reserved.  
  4.  *
  5.  * Permission to use, copy, modify, and distribute this software and its
  6.  * documentation for any purpose, without fee, and without written agreement is
  7.  * hereby granted, provided that the above copyright notice and the following
  8.  * two paragraphs appear in all copies of this software.
  9.  *
  10.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  11.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  12.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  13.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14.  *
  15.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  16.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  17.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  18.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  19.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  20.  */
  21. /* This file contains C code that implements
  22.  * the video decoder model.
  23.  */
  24.  
  25. #include <config.h>
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <assert.h>
  29.  
  30. #ifndef MIPS
  31. #include <sys/time.h>
  32. #else
  33. #include <sys/types.h>
  34. #include <sys/system.h>
  35. #endif
  36.  
  37. #include "globals.h"
  38. #include "decoders.h"
  39. #include "video.h"
  40. #include "util.h"
  41. #include "proto.h"
  42.  
  43. /* Declarations of functions. */
  44. static void ReconIMBlock();
  45. static void ReconPMBlock();
  46. static void ReconBMBlock();
  47. static void ReconBiMBlock();
  48. static void ReconSkippedBlock();
  49. static void DoPictureDisplay();
  50. static int ParseSeqHead();
  51. static int ParseGOP();
  52. static int ParsePicture();
  53. static int ParseSlice();
  54. static int ParseMacroBlock();
  55. static void ProcessSkippedPFrameMBlocks();
  56. static void ProcessSkippedBFrameMBlocks();
  57.  
  58. char *ditherFlags;
  59.  
  60. /* Macro for returning 1 if num is positive, -1 if negative, 0 if 0. */
  61.  
  62. #define Sign(num) ((num > 0) ? 1 : ((num == 0) ? 0 : -1))
  63.  
  64. /* Declare global pointer to vid stream used for current decoding. */
  65.  
  66. VidStream *curVidStream = NULL;
  67.  
  68. /* Set up array for fast conversion from zig zag order to row/column
  69.    coordinates.
  70. */
  71.  
  72. int zigzag[64][2] = {
  73.   0, 0, 1, 0, 0, 1, 0, 2, 1, 1, 2, 0, 3, 0, 2, 1, 1, 2, 0, 3, 0, 4, 1, 3,
  74.   2, 2, 3, 1, 4, 0, 5, 0, 4, 1, 3, 2, 2, 3, 1, 4, 0, 5, 0, 6, 1, 5, 2, 4,
  75.   3, 3, 4, 2, 5, 1, 6, 0, 7, 0, 6, 1, 5, 2, 4, 3, 3, 4, 2, 5, 1, 6, 0, 7,
  76.   1, 7, 2, 6, 3, 5, 4, 4, 5, 3, 6, 2, 7, 1, 7, 2, 6, 3, 5, 4, 4, 5, 3, 6,
  77.   2, 7, 3, 7, 4, 6, 5, 5, 6, 4, 7, 3, 7, 4, 6, 5, 5, 6, 4, 7, 5, 7, 6, 6,
  78. 7, 5, 7, 6, 6, 7, 7, 7};
  79. /* Array mapping zigzag to array pointer offset. */
  80.  
  81. int zigzag_direct[64] = {
  82.   0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12,
  83.   19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35,
  84.   42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
  85. 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63};
  86. /* Set up array for fast conversion from row/column coordinates to
  87.    zig zag order.
  88. */
  89.  
  90. int scan[8][8] = {
  91.   {0, 1, 5, 6, 14, 15, 27, 28},
  92.   {2, 4, 7, 13, 16, 26, 29, 42},
  93.   {3, 8, 12, 17, 25, 30, 41, 43},
  94.   {9, 11, 18, 24, 31, 40, 44, 53},
  95.   {10, 19, 23, 32, 39, 45, 52, 54},
  96.   {20, 22, 33, 38, 46, 51, 55, 60},
  97.   {21, 34, 37, 47, 50, 56, 59, 61},
  98. {35, 36, 48, 49, 57, 58, 62, 63}};
  99. /* Initialize P and B skip flags. */
  100.  
  101. static int No_P_Flag = 0;
  102. static int No_B_Flag = 0;
  103.  
  104. /* Max lum, chrom indices for illegal block checking. */
  105.  
  106. static int lmaxx;
  107. static int lmaxy;
  108. static int cmaxx;
  109. static int cmaxy;
  110.  
  111. /*
  112.  * We use a lookup table to make sure values stay in the 0..255 range.
  113.  * Since this is cropping (ie, x = (x < 0)?0:(x>255)?255:x; ), wee call this
  114.  * table the "crop table".
  115.  * MAX_NEG_CROP is the maximum neg/pos value we can handle.
  116.  */
  117.  
  118. #define MAX_NEG_CROP 384
  119. #define NUM_CROP_ENTRIES (256+2*MAX_NEG_CROP)
  120. #define assertCrop(x)    assert(((x) >= -MAX_NEG_CROP) && \
  121.                    ((x) <= 256+MAX_NEG_CROP))
  122. static unsigned char cropTbl[NUM_CROP_ENTRIES];
  123.  
  124.  
  125.  
  126. /*
  127.  *--------------------------------------------------------------
  128.  *
  129.  * NewVidStream --
  130.  *
  131.  *    Allocates and initializes a VidStream structure. Takes
  132.  *      as parameter requested size for buffer length.
  133.  *
  134.  * Results:
  135.  *    A pointer to the new VidStream structure.
  136.  *
  137.  * Side effects:
  138.  *      None.
  139.  *
  140.  *--------------------------------------------------------------
  141.  */
  142.  
  143. VidStream *
  144. NewVidStream(bufLength)
  145.   int bufLength;
  146. {
  147.   int i, j;
  148.   VidStream *new;
  149.   static unsigned char default_intra_matrix[64] = {
  150.     8, 16, 19, 22, 26, 27, 29, 34,
  151.     16, 16, 22, 24, 27, 29, 34, 37,
  152.     19, 22, 26, 27, 29, 34, 34, 38,
  153.     22, 22, 26, 27, 29, 34, 37, 40,
  154.     22, 26, 27, 29, 32, 35, 40, 48,
  155.     26, 27, 29, 32, 35, 40, 48, 58,
  156.     26, 27, 29, 34, 38, 46, 56, 69,
  157.   27, 29, 35, 38, 46, 56, 69, 83};
  158.  
  159.   /* Check for legal buffer length. */
  160.  
  161.   if (bufLength < 4)
  162.     return NULL;
  163.  
  164.   /* Make buffer length multiple of 4. */
  165.  
  166.   bufLength = (bufLength + 3) >> 2;
  167.  
  168.   /* Allocate memory for new structure. */
  169.  
  170.   new = (VidStream *) malloc(sizeof(VidStream));
  171.  
  172.   /* Initialize pointers to extension and user data. */
  173.  
  174.   new->group.ext_data = new->group.user_data =
  175.     new->picture.extra_info = new->picture.user_data =
  176.     new->picture.ext_data = new->slice.extra_info =
  177.     new->ext_data = new->user_data = NULL;
  178.  
  179.   /* Copy default intra matrix. */
  180.  
  181.   for (i = 0; i < 8; i++) {
  182.     for (j = 0; j < 8; j++) {
  183.       new->intra_quant_matrix[j][i] = default_intra_matrix[i * 8 + j];
  184.     }
  185.   }
  186.  
  187.   /* Initialize crop table. */
  188.  
  189.   for (i = (-MAX_NEG_CROP); i < NUM_CROP_ENTRIES - MAX_NEG_CROP; i++) {
  190.     if (i <= 0) {
  191.       cropTbl[i + MAX_NEG_CROP] = 0;
  192.     } else if (i >= 255) {
  193.       cropTbl[i + MAX_NEG_CROP] = 255;
  194.     } else {
  195.       cropTbl[i + MAX_NEG_CROP] = i;
  196.     }
  197.   }
  198.  
  199.   /* Initialize non intra quantization matrix. */
  200.  
  201.   for (i = 0; i < 8; i++) {
  202.     for (j = 0; j < 8; j++) {
  203.       new->non_intra_quant_matrix[j][i] = 16;
  204.     }
  205.   }
  206.  
  207.   /* Initialize pointers to image spaces. */
  208.  
  209.   new->current = new->past = new->future = NULL;
  210.   for (i = 0; i < RING_BUF_SIZE; i++) {
  211.     new->ring[i] = NULL;
  212.   }
  213.  
  214.   /* Create buffer. */
  215.  
  216.   new->buf_start = (unsigned int *) malloc(bufLength * 4);
  217.  
  218.   /*
  219.    * Set max_buf_length to one less than actual length to deal with messy
  220.    * data without proper seq. end codes.
  221.    */
  222.  
  223.   new->max_buf_length = bufLength - 1;
  224.  
  225.   /* Initialize bitstream i/o fields. */
  226.  
  227.   new->bit_offset = 0;
  228.   new->buf_length = 0;
  229.   new->buffer = new->buf_start;
  230.  
  231.  
  232.   /* Return structure. */
  233.  
  234.   return new;
  235. }
  236.  
  237.  
  238.  
  239. /*
  240.  *--------------------------------------------------------------
  241.  *
  242.  * DestroyVidStream --
  243.  *
  244.  *    Deallocates a VidStream structure.
  245.  *
  246.  * Results:
  247.  *      None.
  248.  *
  249.  * Side effects:
  250.  *    None.
  251.  *
  252.  *--------------------------------------------------------------
  253.  */
  254. void
  255. DestroyVidStream(astream)
  256.   VidStream *astream;
  257. {
  258.   int i;
  259.  
  260.   if (astream->ext_data != NULL)
  261.     free(astream->ext_data);
  262.  
  263.   if (astream->user_data != NULL)
  264.     free(astream->user_data);
  265.  
  266.   if (astream->group.ext_data != NULL)
  267.     free(astream->group.ext_data);
  268.  
  269.   if (astream->group.user_data != NULL)
  270.     free(astream->group.user_data);
  271.  
  272.   if (astream->picture.extra_info != NULL)
  273.     free(astream->picture.extra_info);
  274.  
  275.   if (astream->picture.ext_data != NULL)
  276.     free(astream->picture.ext_data);
  277.  
  278.   if (astream->picture.user_data != NULL)
  279.     free(astream->picture.user_data);
  280.  
  281.   if (astream->slice.extra_info != NULL)
  282.     free(astream->slice.extra_info);
  283.  
  284.   if (astream->buf_start != NULL)
  285.     free(astream->buf_start);
  286.  
  287.   for (i = 0; i < RING_BUF_SIZE; i++) {
  288.     if (astream->ring[i] != NULL) {
  289.       DestroyPictImage(astream->ring[i]);
  290.       astream->ring[i] = NULL;
  291.     }
  292.   }
  293.  
  294.   free((char *) astream);
  295. }
  296.  
  297.  
  298.  
  299.  
  300. /*
  301.  *--------------------------------------------------------------
  302.  *
  303.  * NewPictImage --
  304.  *
  305.  *    Allocates and initializes a PictImage structure.
  306.  *      The width and height of the image space are passed in
  307.  *      as parameters.
  308.  *
  309.  * Results:
  310.  *    A pointer to the new PictImage structure.
  311.  *
  312.  * Side effects:
  313.  *    None.
  314.  *
  315.  *--------------------------------------------------------------
  316.  */
  317.  
  318. PictImage *
  319. NewPictImage(width, height)
  320.   unsigned int width, height;
  321. {
  322.   PictImage *new;
  323.  
  324.   /* Allocate memory space for new structure. */
  325.  
  326.   new = (PictImage *) malloc(sizeof(PictImage));
  327.  
  328.  
  329.   /* Allocate memory for image spaces. */
  330.  
  331.   if ((ditherType == Twox2_DITHER) || (ditherType == FULL_COLOR_DITHER)) {
  332.     new->display = (unsigned char *) malloc(width * height * 4);
  333.   } else {
  334.     new->display = (unsigned char *) malloc(width * height);
  335.   }
  336.  
  337.   new->luminance = (unsigned char *) malloc(width * height);
  338.   new->Cr = (unsigned char *) malloc(width * height / 4);
  339.   new->Cb = (unsigned char *) malloc(width * height / 4);
  340.  
  341.   /* Reset locked flag. */
  342.  
  343.   new->locked = 0;
  344.  
  345.   /* Return pointer to new structure. */
  346.  
  347.   return new;
  348. }
  349.  
  350.  
  351.  
  352. /*
  353.  *--------------------------------------------------------------
  354.  *
  355.  * DestroyPictImage --
  356.  *
  357.  *    Deallocates a PictImage structure.
  358.  *
  359.  * Results:
  360.  *      None.
  361.  *
  362.  * Side effects:
  363.  *    None.
  364.  *
  365.  *--------------------------------------------------------------
  366.  */
  367. void
  368. DestroyPictImage(apictimage)
  369.   PictImage *apictimage;
  370. {
  371.   if (apictimage->luminance != NULL) {
  372.     free(apictimage->luminance);
  373.   }
  374.   if (apictimage->Cr != NULL) {
  375.     free(apictimage->Cr);
  376.   }
  377.   if (apictimage->Cb != NULL) {
  378.     free(apictimage->Cb);
  379.   }
  380.  
  381.   if (apictimage->display != NULL) {
  382.     free(apictimage->display);
  383.   }
  384.   free(apictimage);
  385. }
  386.  
  387.  
  388.  
  389. /*
  390.  *--------------------------------------------------------------
  391.  *
  392.  * mpegVidRsrc --
  393.  *
  394.  *      Parses bit stream until MB_QUANTUM number of
  395.  *      macroblocks have been decoded or current slice or
  396.  *      picture ends, whichever comes first. If the start
  397.  *      of a frame is encountered, the frame is time stamped
  398.  *      with the value passed in time_stamp. If the value
  399.  *      passed in buffer is not null, the video stream buffer
  400.  *      is set to buffer and the length of the buffer is
  401.  *      expected in value passed in through length. The current
  402.  *      video stream is set to vid_stream. If vid_stream
  403.  *      is passed as NULL, a new VidStream structure is created
  404.  *      and initialized and used as the current video stream.
  405.  *
  406.  *      Note that multiple calls to mpegVidRsrc are required 
  407.  *      decode each frame in the movie.  When mpegVidRsrc has
  408.  *      determined that it has decoded a single frame, it calls
  409.  *      DoPictureDisplay(), which converts from YUV space to RGB
  410.  *      space and then calls ExecuteDisplay().  ExecuteDisplay()
  411.  *      is passed the currently-being-decoded video stream, which
  412.  *      has a field called current (a pointer to a PictImage) 
  413.  *      which in turn points to the raw image data in some 
  414.  *      X-friendly RGB format.
  415.  *     
  416.  *      When the last frame has been decoded, mpegVidRsrc calls
  417.  *      ExecuteDisplay() one last time (if necessary), destroys
  418.  *      the video stream, and returns NULL.
  419.  *
  420.  * Results:
  421.  *      A pointer to the video stream structure used, or NULL
  422.  *      if the last frame has just been finished.
  423.  *
  424.  * Side effects:
  425.  *      Bit stream is irreversibly parsed. If a picture is completed,
  426.  *      a function is called to display the frame at the correct time.
  427.  *
  428.  *--------------------------------------------------------------
  429.  */
  430.  
  431. VidStream *
  432. mpegVidRsrc(time_stamp, vid_stream)
  433.   TimeStamp time_stamp;
  434.   VidStream *vid_stream;
  435. {
  436.   static int num_calls = 0;
  437.   unsigned int data;
  438.   int i, status;
  439.   long int ftell (FILE *stream);
  440.  
  441.   /* If vid_stream is null, create new VidStream structure. */
  442.  
  443.   if (vid_stream == NULL) {
  444.     return NULL;
  445.   }
  446.   /*
  447.    * Set global curVidStream to vid_stream. Necessary because bit i/o use
  448.    * curVidStream and are not passed vid_stream. Also set global bitstream
  449.    * parameters.
  450.    */
  451.  
  452.   curVidStream = vid_stream;
  453.   bitOffset = curVidStream->bit_offset;
  454. #ifdef UTIL2
  455.   curBits = *curVidStream->buffer << bitOffset;
  456. #else
  457.   curBits = *curVidStream->buffer;
  458. #endif
  459.   bufLength = curVidStream->buf_length;
  460.   bitBuffer = curVidStream->buffer;
  461.  
  462.   /*
  463.    * If called for the first time, find start code, make sure it is a
  464.    * sequence start code.
  465.    */
  466.  
  467.   if (num_calls == 0) {
  468.     next_start_code();
  469.     show_bits32(data);
  470.     if (data != SEQ_START_CODE) {
  471.       fprintf(stderr, "This is not an MPEG stream.");
  472.       DestroyVidStream(curVidStream);
  473.       exit(1);
  474.     }
  475.     num_calls++;
  476.   }
  477.  
  478.   /* Get next 32 bits (size of start codes). */
  479.  
  480.   show_bits32(data);
  481.   /*
  482.    * Process according to start code (or parse macroblock if not a start code
  483.    * at all.
  484.    */
  485.  
  486.   dprintf ("mpegVidRsrc: offset %6ld: found ", ftell (input));
  487.   switch (data) {
  488.  
  489.   case SEQ_END_CODE:
  490.  
  491.     /* Display last frame. */
  492.  
  493.     dprintf ("SEQ_END_CODE\n");
  494.     if (vid_stream->future != NULL) {
  495.       vid_stream->current = vid_stream->future;
  496.       ExecuteDisplay(vid_stream);
  497.     }
  498.     
  499.     /* Sequence done.  Return NULL to caller to indicate just that. */
  500.  
  501.  
  502.     DestroyVidStream(curVidStream);
  503.     dprintf ("mpegVidRsrc: movie done, returning NULL\n");
  504.     return (NULL);
  505.     break;
  506.  
  507.   case SEQ_START_CODE:
  508.  
  509.     /* Sequence start code. Parse sequence header. */
  510.  
  511.     dprintf ("SEQ_START_CODE\n");
  512.     if (ParseSeqHead(vid_stream) != PARSE_OK)
  513.       goto error;
  514.  
  515.     /*
  516.      * Return after sequence start code so that application above can use
  517.      * info in header.
  518.      */
  519.  
  520.     goto done;
  521.  
  522.   case GOP_START_CODE:
  523.  
  524.     /* Group of Pictures start code. Parse gop header. */
  525.  
  526.     dprintf ("GOP_START_CODE\n");
  527.     if (ParseGOP(vid_stream) != PARSE_OK)
  528.       goto error;
  529.  
  530.  
  531.   case PICTURE_START_CODE:
  532.  
  533.     /* Picture start code. Parse picture header and first slice header. */
  534.  
  535.     dprintf ("PICTURE_START_CODE\n");
  536.     status = ParsePicture(vid_stream, time_stamp);
  537.  
  538.     if (status == SKIP_PICTURE) {
  539.       next_start_code();
  540. /*    fprintf(stderr, "Skipping picture...");      */
  541.       while (!next_bits(32, PICTURE_START_CODE)) {
  542.     if (next_bits(32, GOP_START_CODE))
  543.       break;
  544.     else if (next_bits(32, SEQ_END_CODE))
  545.       break;
  546.     flush_bits(24);
  547.     next_start_code();
  548.       }
  549. /*    fprintf(stderr, "Done.\n");     */
  550.       goto done;   
  551.     } else if (status != PARSE_OK)
  552.       goto error;
  553.  
  554.  
  555.     if (ParseSlice(vid_stream) != PARSE_OK)
  556.       goto error;
  557.     break;
  558.  
  559.   default:
  560.  
  561.     /* Check for slice start code. */
  562.  
  563.     dprintf ("something else (%08x)\n", data);
  564.     if ((data >= SLICE_MIN_START_CODE) && (data <= SLICE_MAX_START_CODE)) {
  565.  
  566.       /* Slice start code. Parse slice header. */
  567.  
  568.       if (ParseSlice(vid_stream) != PARSE_OK)
  569.     goto error;
  570.     }
  571.     break;
  572.   }
  573.  
  574.   /* Parse next MB_QUANTUM macroblocks. */
  575.  
  576.   for (i = 0; i < MB_QUANTUM; i++) {
  577.  
  578.     /* Check to see if actually a startcode and not a macroblock. */
  579.  
  580.     if (!next_bits(23, 0x00000000)) {
  581.  
  582.       /* Not start code. Parse Macroblock. */
  583.  
  584.       if (ParseMacroBlock(vid_stream) != PARSE_OK)
  585.     goto error;
  586.  
  587.     } else {
  588.  
  589.       /* Not macroblock, actually start code. Get start code. */
  590.  
  591.       next_start_code();
  592.       show_bits32(data);
  593.  
  594.       /*
  595.        * If start code is outside range of slice start codes, frame is
  596.        * complete, display frame.
  597.        */
  598.  
  599.       if ((data < SLICE_MIN_START_CODE) || (data > SLICE_MAX_START_CODE)) {
  600.     DoPictureDisplay(vid_stream);
  601.       }
  602.       break;
  603.     }
  604.   }
  605.  
  606.   /* Return pointer to video stream structure. */
  607.  
  608.   goto done;
  609.  
  610. error:
  611.   fprintf(stderr, "Error!!!!\n");
  612.   next_start_code();
  613.   goto done;
  614.  
  615. done:
  616.  
  617.   /* Copy global bit i/o variables back into vid_stream. */
  618.  
  619.   vid_stream->buffer = bitBuffer;
  620.   vid_stream->buf_length = bufLength;
  621.   vid_stream->bit_offset = bitOffset;
  622.  
  623.   return vid_stream;
  624.  
  625. }
  626.  
  627.  
  628.  
  629. /*
  630.  *--------------------------------------------------------------
  631.  *
  632.  * ParseSeqHead --
  633.  *
  634.  *      Assumes bit stream is at the begining of the sequence
  635.  *      header start code. Parses off the sequence header.
  636.  *
  637.  * Results:
  638.  *      Fills the vid_stream structure with values derived and
  639.  *      decoded from the sequence header. Allocates the pict image
  640.  *      structures based on the dimensions of the image space
  641.  *      found in the sequence header.
  642.  *
  643.  * Side effects:
  644.  *      Bit stream irreversibly parsed off.
  645.  *
  646.  *--------------------------------------------------------------
  647.  */
  648.  
  649. static int
  650. ParseSeqHead(vid_stream)
  651.   VidStream *vid_stream;
  652. {
  653.  
  654.   unsigned int data;
  655.   int i;
  656.  
  657.   /* Flush off sequence start code. */
  658.  
  659.   flush_bits32;
  660.  
  661.   /* Get horizontal size of image space. */
  662.  
  663.   get_bits12(data);
  664.   vid_stream->h_size = data;
  665.  
  666.   /* Get vertical size of image space. */
  667.  
  668.   get_bits12(data);
  669.   vid_stream->v_size = data;
  670.  
  671.   /* Calculate macroblock width and height of image space. */
  672.  
  673.   vid_stream->mb_width = (vid_stream->h_size + 15) / 16;
  674.   vid_stream->mb_height = (vid_stream->v_size + 15) / 16;
  675.  
  676.   /* If dither type is MBORDERED allocate ditherFlags. */
  677.  
  678. #if (ENABLE_DITHER)
  679.   if (ditherType == MBORDERED_DITHER) {
  680.     ditherFlags = (char *) malloc(vid_stream->mb_width*vid_stream->mb_height);
  681.   }
  682. #endif
  683.  
  684.   /* Initialize lmaxx, lmaxy, cmaxx, cmaxy. */
  685.  
  686.   lmaxx = vid_stream->mb_width*16-1;
  687.   lmaxy = vid_stream->mb_height*16-1;
  688.   cmaxx = vid_stream->mb_width*8-1;
  689.   cmaxy = vid_stream->mb_height*8-1;
  690.  
  691.   /*
  692.    * Initialize ring buffer of pict images now that dimensions of image space
  693.    * are known.
  694.    */
  695.  
  696.   if (vid_stream->ring[0] == NULL) {
  697.     for (i = 0; i < RING_BUF_SIZE; i++) {
  698.       vid_stream->ring[i] = NewPictImage(vid_stream->mb_width * 16,
  699.                      vid_stream->mb_height * 16);
  700.     }
  701.   }
  702.  
  703.   /* Parse of aspect ratio code. */
  704.  
  705.   get_bits4(data);
  706.   vid_stream->aspect_ratio = (unsigned char) data;
  707.  
  708.   /* Parse off picture rate code. */
  709.  
  710.   get_bits4(data);
  711.   vid_stream->picture_rate = (unsigned char) data;
  712.  
  713.   /* Parse off bit rate. */
  714.  
  715.   get_bits18(data);
  716.   vid_stream->bit_rate = data;
  717.  
  718.   /* Flush marker bit. */
  719.  
  720.   flush_bits(1);
  721.  
  722.   /* Parse off vbv buffer size. */
  723.  
  724.   get_bits10(data);
  725.   vid_stream->vbv_buffer_size = data;
  726.  
  727.   /* Parse off contrained parameter flag. */
  728.  
  729.   get_bits1(data);
  730.   if (data) {
  731.     vid_stream->const_param_flag = TRUE;
  732.   } else
  733.     vid_stream->const_param_flag = FALSE;
  734.  
  735.   /*
  736.    * If intra_quant_matrix_flag set, parse off intra quant matrix values.
  737.    */
  738.  
  739.   get_bits1(data);
  740.   if (data) {
  741.     for (i = 0; i < 64; i++) {
  742.       get_bits8(data);
  743.  
  744.       vid_stream->intra_quant_matrix[zigzag[i][1]][zigzag[i][0]] =
  745.     (unsigned char) data;
  746.     }
  747.   }
  748.   /*
  749.    * If non intra quant matrix flag set, parse off non intra quant matrix
  750.    * values.
  751.    */
  752.  
  753.   get_bits1(data);
  754.   if (data) {
  755.     for (i = 0; i < 64; i++) {
  756.       get_bits8(data);
  757.  
  758.       vid_stream->non_intra_quant_matrix[zigzag[i][1]][zigzag[i][0]] =
  759.     (unsigned char) data;
  760.     }
  761.   }
  762.   /* Go to next start code. */
  763.  
  764.   next_start_code();
  765.  
  766.   /*
  767.    * If next start code is extension start code, parse off extension data.
  768.    */
  769.  
  770.   if (next_bits(32, EXT_START_CODE)) {
  771.     flush_bits32;
  772.     if (vid_stream->ext_data != NULL) {
  773.       free(vid_stream->ext_data);
  774.       vid_stream->ext_data = NULL;
  775.     }
  776.     vid_stream->ext_data = get_ext_data();
  777.   }
  778.   /* If next start code is user start code, parse off user data. */
  779.  
  780.   if (next_bits(32, USER_START_CODE)) {
  781.     flush_bits32;
  782.     if (vid_stream->user_data != NULL) {
  783.       free(vid_stream->user_data);
  784.       vid_stream->user_data = NULL;
  785.     }
  786.     vid_stream->user_data = get_ext_data();
  787.   }
  788.   return PARSE_OK;
  789. }
  790.  
  791.  
  792.  
  793. /*
  794.  *--------------------------------------------------------------
  795.  *
  796.  * ParseGOP --
  797.  *
  798.  *      Parses of group of pictures header from bit stream
  799.  *      associated with vid_stream.
  800.  *
  801.  * Results:
  802.  *      Values in gop header placed into video stream structure.
  803.  *
  804.  * Side effects:
  805.  *      Bit stream irreversibly parsed.
  806.  *
  807.  *--------------------------------------------------------------
  808.  */
  809.  
  810. static int
  811. ParseGOP(vid_stream)
  812.   VidStream *vid_stream;
  813. {
  814.   unsigned int data;
  815.  
  816.   /* Flush group of pictures start code. WWWWWWOOOOOOOSSSSSSHHHHH!!! */
  817.  
  818.   flush_bits32;
  819.  
  820.   /* Parse off drop frame flag. */
  821.  
  822.   get_bits1(data);
  823.   if (data) {
  824.     vid_stream->group.drop_flag = TRUE;
  825.   } else
  826.     vid_stream->group.drop_flag = FALSE;
  827.  
  828.   /* Parse off hour component of time code. */
  829.  
  830.   get_bits5(data);
  831.   vid_stream->group.tc_hours = data;
  832.  
  833.   /* Parse off minute component of time code. */
  834.  
  835.   get_bits6(data);
  836.   vid_stream->group.tc_minutes = data;
  837.  
  838.   /* Flush marker bit. */
  839.  
  840.   flush_bits(1);
  841.  
  842.   /* Parse off second component of time code. */
  843.  
  844.   get_bits6(data);
  845.   vid_stream->group.tc_seconds = data;
  846.  
  847.   /* Parse off picture count component of time code. */
  848.  
  849.   get_bits6(data);
  850.   vid_stream->group.tc_pictures = data;
  851.  
  852.   /* Parse off closed gop and broken link flags. */
  853.  
  854.   get_bits2(data);
  855.   if (data > 1) {
  856.     vid_stream->group.closed_gop = TRUE;
  857.     if (data > 2) {
  858.       vid_stream->group.broken_link = TRUE;
  859.     } else
  860.       vid_stream->group.broken_link = FALSE;
  861.   } else {
  862.     vid_stream->group.closed_gop = FALSE;
  863.     if (data) {
  864.       vid_stream->group.broken_link = TRUE;
  865.     } else
  866.       vid_stream->group.broken_link = FALSE;
  867.   }
  868.  
  869.   /* Goto next start code. */
  870.  
  871.   next_start_code();
  872.  
  873.   /* If next start code is extension data, parse off extension data. */
  874.  
  875.   if (next_bits(32, EXT_START_CODE)) {
  876.     flush_bits32;
  877.     if (vid_stream->group.ext_data != NULL) {
  878.       free(vid_stream->group.ext_data);
  879.       vid_stream->group.ext_data = NULL;
  880.     }
  881.     vid_stream->group.ext_data = get_ext_data();
  882.   }
  883.   /* If next start code is user data, parse off user data. */
  884.  
  885.   if (next_bits(32, USER_START_CODE)) {
  886.     flush_bits32;
  887.     if (vid_stream->group.user_data != NULL) {
  888.       free(vid_stream->group.user_data);
  889.       vid_stream->group.user_data = NULL;
  890.     }
  891.     vid_stream->group.user_data = get_ext_data();
  892.   }
  893.   return PARSE_OK;
  894. }
  895.  
  896.  
  897.  
  898. /*
  899.  *--------------------------------------------------------------
  900.  *
  901.  * ParsePicture --
  902.  *
  903.  *      Parses picture header. Marks picture to be presented
  904.  *      at particular time given a time stamp.
  905.  *
  906.  * Results:
  907.  *      Values from picture header put into video stream structure.
  908.  *
  909.  * Side effects:
  910.  *      Bit stream irreversibly parsed.
  911.  *
  912.  *--------------------------------------------------------------
  913.  */
  914.  
  915. static int
  916. ParsePicture(vid_stream, time_stamp)
  917.   VidStream *vid_stream;
  918.   TimeStamp time_stamp;
  919. {
  920.   unsigned int data;
  921.   int i;
  922.  
  923.   /* Flush header start code. */
  924.   flush_bits32;
  925.  
  926.   /* Parse off temporal reference. */
  927.   get_bits10(data);
  928.   vid_stream->picture.temp_ref = data;
  929.  
  930.   /* Parse of picture type. */
  931.   get_bits3(data);
  932.   vid_stream->picture.code_type = data;
  933.  
  934.   if ((vid_stream->picture.code_type == B_TYPE) &&
  935.       (No_B_Flag ||
  936.        (vid_stream->past == NULL) ||
  937.        (vid_stream->future == NULL)))
  938.     return SKIP_PICTURE;
  939.  
  940.   if ((vid_stream->picture.code_type == P_TYPE) &&
  941.       (No_P_Flag || (vid_stream->future == NULL)))
  942.     return SKIP_PICTURE;
  943.  
  944.   /* Parse off vbv buffer delay value. */
  945.   get_bits16(data);
  946.   vid_stream->picture.vbv_delay = data;
  947.  
  948.   /* If P or B type frame... */
  949.  
  950.   if ((vid_stream->picture.code_type == 2) || (vid_stream->picture.code_type == 3)) {
  951.  
  952.     /* Parse off forward vector full pixel flag. */
  953.     get_bits1(data);
  954.     if (data)
  955.       vid_stream->picture.full_pel_forw_vector = TRUE;
  956.     else
  957.       vid_stream->picture.full_pel_forw_vector = FALSE;
  958.  
  959.     /* Parse of forw_r_code. */
  960.     get_bits3(data);
  961.  
  962.     /* Decode forw_r_code into forw_r_size and forw_f. */
  963.  
  964.     vid_stream->picture.forw_r_size = data - 1;
  965.     vid_stream->picture.forw_f = (1 << vid_stream->picture.forw_r_size);
  966.   }
  967.   /* If B type frame... */
  968.  
  969.   if (vid_stream->picture.code_type == 3) {
  970.  
  971.     /* Parse off back vector full pixel flag. */
  972.     get_bits1(data);
  973.     if (data)
  974.       vid_stream->picture.full_pel_back_vector = TRUE;
  975.     else
  976.       vid_stream->picture.full_pel_back_vector = FALSE;
  977.  
  978.     /* Parse off back_r_code. */
  979.     get_bits3(data);
  980.  
  981.     /* Decode back_r_code into back_r_size and back_f. */
  982.  
  983.     vid_stream->picture.back_r_size = data - 1;
  984.     vid_stream->picture.back_f = (1 << vid_stream->picture.back_r_size);
  985.   }
  986.   /* Get extra bit picture info. */
  987.  
  988.   if (vid_stream->picture.extra_info != NULL) {
  989.     free(vid_stream->picture.extra_info);
  990.     vid_stream->picture.extra_info = NULL;
  991.   }
  992.   vid_stream->picture.extra_info = get_extra_bit_info();
  993.  
  994.   /* Goto next start code. */
  995.   next_start_code();
  996.  
  997.   /* If start code is extension start code, parse off extension data. */
  998.  
  999.   if (next_bits(32, EXT_START_CODE)) {
  1000.     flush_bits32;
  1001.  
  1002.     if (vid_stream->picture.ext_data != NULL) {
  1003.       free(vid_stream->picture.ext_data);
  1004.       vid_stream->picture.ext_data = NULL;
  1005.     }
  1006.     vid_stream->picture.ext_data = get_ext_data();
  1007.   }
  1008.   /* If start code is user start code, parse off user data. */
  1009.  
  1010.   if (next_bits(32, USER_START_CODE)) {
  1011.     flush_bits32;
  1012.  
  1013.     if (vid_stream->picture.user_data != NULL) {
  1014.       free(vid_stream->picture.user_data);
  1015.       vid_stream->picture.user_data = NULL;
  1016.     }
  1017.     vid_stream->picture.user_data = get_ext_data();
  1018.   }
  1019.   /* Find a pict image structure in ring buffer not currently locked. */
  1020.  
  1021.   i = 0;
  1022.  
  1023.   while (vid_stream->ring[i]->locked != 0) {
  1024.     if (++i >= RING_BUF_SIZE) {
  1025.       perror("Fatal error. Ring buffer full.");
  1026.       exit(1);
  1027.     }
  1028.   }
  1029.  
  1030.   /* Set current pict image structure to the one just found in ring. */
  1031.  
  1032.   vid_stream->current = vid_stream->ring[i];
  1033.  
  1034.   /* Set time stamp. */
  1035.  
  1036.   vid_stream->current->show_time = time_stamp;
  1037.  
  1038.   /* Reset past macroblock address field. */
  1039.  
  1040.   vid_stream->mblock.past_mb_addr = -1;
  1041.  
  1042.   return PARSE_OK;
  1043. }
  1044.  
  1045.  
  1046.  
  1047. /*
  1048.  *--------------------------------------------------------------
  1049.  *
  1050.  * ParseSlice --
  1051.  *
  1052.  *      Parses off slice header.
  1053.  *
  1054.  * Results:
  1055.  *      Values found in slice header put into video stream structure.
  1056.  *
  1057.  * Side effects:
  1058.  *      Bit stream irreversibly parsed.
  1059.  *
  1060.  *--------------------------------------------------------------
  1061.  */
  1062.  
  1063. static int
  1064. ParseSlice(vid_stream)
  1065.   VidStream *vid_stream;
  1066. {
  1067.   unsigned int data;
  1068.  
  1069.   /* Flush slice start code. */
  1070.  
  1071.   flush_bits(24);
  1072.  
  1073.   /* Parse off slice vertical position. */
  1074.  
  1075.   get_bits8(data);
  1076.   vid_stream->slice.vert_pos = data;
  1077.  
  1078.   /* Parse off quantization scale. */
  1079.  
  1080.   get_bits5(data);
  1081.   vid_stream->slice.quant_scale = data;
  1082.  
  1083.   /* Parse off extra bit slice info. */
  1084.  
  1085.   if (vid_stream->slice.extra_info != NULL) {
  1086.     free(vid_stream->slice.extra_info);
  1087.     vid_stream->slice.extra_info = NULL;
  1088.   }
  1089.   vid_stream->slice.extra_info = get_extra_bit_info();
  1090.  
  1091.   /* Reset past intrablock address. */
  1092.  
  1093.   vid_stream->mblock.past_intra_addr = -2;
  1094.  
  1095.   /* Reset previous recon motion vectors. */
  1096.  
  1097.   vid_stream->mblock.recon_right_for_prev = 0;
  1098.   vid_stream->mblock.recon_down_for_prev = 0;
  1099.   vid_stream->mblock.recon_right_back_prev = 0;
  1100.   vid_stream->mblock.recon_down_back_prev = 0;
  1101.  
  1102.   /* Reset macroblock address. */
  1103.  
  1104.   vid_stream->mblock.mb_address = ((vid_stream->slice.vert_pos - 1) *
  1105.                    vid_stream->mb_width) - 1;
  1106.  
  1107.   /* Reset past dct dc y, cr, and cb values. */
  1108.  
  1109.   vid_stream->block.dct_dc_y_past = 1024;
  1110.   vid_stream->block.dct_dc_cr_past = 1024;
  1111.   vid_stream->block.dct_dc_cb_past = 1024;
  1112.  
  1113.   return PARSE_OK;
  1114. }
  1115.  
  1116.  
  1117.  
  1118. /*
  1119.  *--------------------------------------------------------------
  1120.  *
  1121.  * ParseMacroBlock --
  1122.  *
  1123.  *      Parseoff macroblock. Reconstructs DCT values. Applies
  1124.  *      inverse DCT, reconstructs motion vectors, calculates and
  1125.  *      set pixel values for macroblock in current pict image
  1126.  *      structure.
  1127.  *
  1128.  * Results:
  1129.  *      Here's where everything really happens. Welcome to the
  1130.  *      heart of darkness.
  1131.  *
  1132.  * Side effects:
  1133.  *      Bit stream irreversibly parsed off.
  1134.  *
  1135.  *--------------------------------------------------------------
  1136.  */
  1137.  
  1138. static int
  1139. ParseMacroBlock(vid_stream)
  1140.   VidStream *vid_stream;
  1141. {
  1142.   int addr_incr;
  1143.   unsigned int data;
  1144.   int mask, i, recon_right_for, recon_down_for, recon_right_back,
  1145.       recon_down_back;
  1146.   int zero_block_flag;
  1147.   BOOLEAN mb_quant, mb_motion_forw, mb_motion_back, mb_pattern;
  1148.   int no_dith_flag = 0;
  1149.  
  1150.   /*
  1151.    * Parse off macroblock address increment and add to macroblock address.
  1152.    */
  1153.   do {
  1154.     DecodeMBAddrInc(addr_incr);
  1155.     if (addr_incr == MB_ESCAPE) {
  1156.       vid_stream->mblock.mb_address += 33;
  1157.       addr_incr = MB_STUFFING;
  1158.     }
  1159.   } while (addr_incr == MB_STUFFING);
  1160.   vid_stream->mblock.mb_address += addr_incr;
  1161.  
  1162.   if (vid_stream->mblock.mb_address > (vid_stream->mb_height *
  1163.                        vid_stream->mb_width - 1))
  1164.     return SKIP_TO_START_CODE;
  1165.  
  1166.   /*
  1167.    * If macroblocks have been skipped, process skipped macroblocks.
  1168.    */
  1169.  
  1170.   if (vid_stream->mblock.mb_address - vid_stream->mblock.past_mb_addr > 1) {
  1171.     if (vid_stream->picture.code_type == P_TYPE)
  1172.       ProcessSkippedPFrameMBlocks(vid_stream);
  1173.     else if (vid_stream->picture.code_type == B_TYPE)
  1174.       ProcessSkippedBFrameMBlocks(vid_stream);
  1175.   }
  1176.   /* Set past macroblock address to current macroblock address. */
  1177.   vid_stream->mblock.past_mb_addr = vid_stream->mblock.mb_address;
  1178.  
  1179.   /* Based on picture type decode macroblock type. */
  1180.   switch (vid_stream->picture.code_type) {
  1181.   case I_TYPE:
  1182.     DecodeMBTypeI(mb_quant, mb_motion_forw, mb_motion_back, mb_pattern,
  1183.           vid_stream->mblock.mb_intra);
  1184.     break;
  1185.  
  1186.   case P_TYPE:
  1187.     DecodeMBTypeP(mb_quant, mb_motion_forw, mb_motion_back, mb_pattern,
  1188.           vid_stream->mblock.mb_intra);
  1189.     break;
  1190.  
  1191.   case B_TYPE:
  1192.     DecodeMBTypeB(mb_quant, mb_motion_forw, mb_motion_back, mb_pattern,
  1193.           vid_stream->mblock.mb_intra);
  1194.     break;
  1195.   }
  1196.  
  1197.   /* If quantization flag set, parse off new quantization scale. */
  1198.  
  1199.   if (mb_quant == TRUE) {
  1200.     get_bits5(data);
  1201.     vid_stream->slice.quant_scale = data;
  1202.   }
  1203.   /* If forward motion vectors exist... */
  1204.   if (mb_motion_forw == TRUE) {
  1205.  
  1206.     /* Parse off and decode horizontal forward motion vector. */
  1207.     DecodeMotionVectors(vid_stream->mblock.motion_h_forw_code);
  1208.  
  1209.     /* If horiz. forward r data exists, parse off. */
  1210.  
  1211.     if ((vid_stream->picture.forw_f != 1) &&
  1212.     (vid_stream->mblock.motion_h_forw_code != 0)) {
  1213.       get_bitsn(vid_stream->picture.forw_r_size, data);
  1214.       vid_stream->mblock.motion_h_forw_r = data;
  1215.     }
  1216.     /* Parse off and decode vertical forward motion vector. */
  1217.     DecodeMotionVectors(vid_stream->mblock.motion_v_forw_code);
  1218.  
  1219.     /* If vert. forw. r data exists, parse off. */
  1220.  
  1221.     if ((vid_stream->picture.forw_f != 1) &&
  1222.     (vid_stream->mblock.motion_v_forw_code != 0)) {
  1223.       get_bitsn(vid_stream->picture.forw_r_size, data);
  1224.       vid_stream->mblock.motion_v_forw_r = data;
  1225.     }
  1226.   }
  1227.   /* If back motion vectors exist... */
  1228.   if (mb_motion_back == TRUE) {
  1229.  
  1230.     /* Parse off and decode horiz. back motion vector. */
  1231.     DecodeMotionVectors(vid_stream->mblock.motion_h_back_code);
  1232.  
  1233.     /* If horiz. back r data exists, parse off. */
  1234.  
  1235.     if ((vid_stream->picture.back_f != 1) &&
  1236.     (vid_stream->mblock.motion_h_back_code != 0)) {
  1237.       get_bitsn(vid_stream->picture.back_r_size, data);
  1238.       vid_stream->mblock.motion_h_back_r = data;
  1239.     }
  1240.     /* Parse off and decode vert. back motion vector. */
  1241.     DecodeMotionVectors(vid_stream->mblock.motion_v_back_code);
  1242.  
  1243.     /* If vert. back r data exists, parse off. */
  1244.  
  1245.     if ((vid_stream->picture.back_f != 1) &&
  1246.     (vid_stream->mblock.motion_v_back_code != 0)) {
  1247.       get_bitsn(vid_stream->picture.back_r_size, data);
  1248.       vid_stream->mblock.motion_v_back_r = data;
  1249.     }
  1250.   }
  1251.  
  1252.   /* If mblock pattern flag set, parse and decode CBP (code block pattern). */
  1253.   if (mb_pattern == TRUE) {
  1254.     DecodeCBP(vid_stream->mblock.cbp);
  1255.   }
  1256.   /* Otherwise, set CBP to zero. */
  1257.   else
  1258.     vid_stream->mblock.cbp = 0;
  1259.  
  1260.  
  1261.   /* Reconstruct motion vectors depending on picture type. */
  1262.   if (vid_stream->picture.code_type == P_TYPE) {
  1263.  
  1264.     /*
  1265.      * If no forw motion vectors, reset previous and current vectors to 0.
  1266.      */
  1267.  
  1268.     if (!mb_motion_forw) {
  1269.       recon_right_for = 0;
  1270.       recon_down_for = 0;
  1271.       vid_stream->mblock.recon_right_for_prev = 0;
  1272.       vid_stream->mblock.recon_down_for_prev = 0;
  1273.     }
  1274.     /*
  1275.      * Otherwise, compute new forw motion vectors. Reset previous vectors to
  1276.      * current vectors.
  1277.      */
  1278.  
  1279.     else {
  1280.       ComputeForwVector(&recon_right_for, &recon_down_for);
  1281.     }
  1282.   }
  1283.   if (vid_stream->picture.code_type == B_TYPE) {
  1284.  
  1285.     /* Reset prev. and current vectors to zero if mblock is intracoded. */
  1286.  
  1287.     if (vid_stream->mblock.mb_intra) {
  1288.       vid_stream->mblock.recon_right_for_prev = 0;
  1289.       vid_stream->mblock.recon_down_for_prev = 0;
  1290.       vid_stream->mblock.recon_right_back_prev = 0;
  1291.       vid_stream->mblock.recon_down_back_prev = 0;
  1292.     } else {
  1293.  
  1294.       /* If no forw vectors, current vectors equal prev. vectors. */
  1295.  
  1296.       if (!mb_motion_forw) {
  1297.     recon_right_for = vid_stream->mblock.recon_right_for_prev;
  1298.     recon_down_for = vid_stream->mblock.recon_down_for_prev;
  1299.       }
  1300.       /*
  1301.        * Otherwise compute forw. vectors. Reset prev vectors to new values.
  1302.        */
  1303.  
  1304.       else {
  1305.         ComputeForwVector(&recon_right_for, &recon_down_for);
  1306.       }
  1307.  
  1308.       /* If no back vectors, set back vectors to prev back vectors. */
  1309.  
  1310.       if (!mb_motion_back) {
  1311.     recon_right_back = vid_stream->mblock.recon_right_back_prev;
  1312.     recon_down_back = vid_stream->mblock.recon_down_back_prev;
  1313.       }
  1314.       /* Otherwise compute new vectors and reset prev. back vectors. */
  1315.  
  1316.       else {
  1317.     ComputeBackVector(&recon_right_back, &recon_down_back);
  1318.       }
  1319.  
  1320.       /*
  1321.        * Store vector existance flags in structure for possible skipped
  1322.        * macroblocks to follow.
  1323.        */
  1324.  
  1325.       vid_stream->mblock.bpict_past_forw = mb_motion_forw;
  1326.       vid_stream->mblock.bpict_past_back = mb_motion_back;
  1327.     }
  1328.   }
  1329.  
  1330.   /* For each possible block in macroblock. */
  1331.   if (ditherType == GRAY_DITHER ||
  1332.       ditherType == MONO_DITHER ||
  1333.       ditherType == MONO_THRESHOLD) {
  1334.     for (mask = 32, i = 0; i < 4; mask >>= 1, i++) {
  1335.  
  1336.       /* If block exists... */
  1337.       if ((vid_stream->mblock.mb_intra) || (vid_stream->mblock.cbp & mask)) {
  1338.     zero_block_flag = 0;
  1339.     ParseReconBlock(i);
  1340.       } else {
  1341.     zero_block_flag = 1;
  1342.       }
  1343.  
  1344.       /* If macroblock is intra coded... */
  1345.       if (vid_stream->mblock.mb_intra) {
  1346.     ReconIMBlock(vid_stream, i);
  1347.       } else if (mb_motion_forw && mb_motion_back) {
  1348.     ReconBiMBlock(vid_stream, i, recon_right_for, recon_down_for,
  1349.               recon_right_back, recon_down_back, zero_block_flag);
  1350.       } else if (mb_motion_forw || (vid_stream->picture.code_type == P_TYPE)) {
  1351.     ReconPMBlock(vid_stream, i, recon_right_for, recon_down_for,
  1352.              zero_block_flag);
  1353.       } else if (mb_motion_back) {
  1354.     ReconBMBlock(vid_stream, i, recon_right_back, recon_down_back,
  1355.              zero_block_flag);
  1356.       }
  1357.     }
  1358.     /* Kill the Chrominace blocks... */
  1359.     if ((vid_stream->mblock.mb_intra) || (vid_stream->mblock.cbp & 0x2)) {
  1360.         ParseAwayBlock(4);
  1361.     }
  1362.     if ((vid_stream->mblock.mb_intra) || (vid_stream->mblock.cbp & 0x1)) {
  1363.         ParseAwayBlock(5);
  1364.     }
  1365.   } else {
  1366. #if (ENABLE_DITHER)
  1367.     if ((ditherType == MBORDERED_DITHER) &&
  1368.     (vid_stream->mblock.cbp == 0) &&
  1369.     (vid_stream->picture.code_type == 3) &&
  1370.     (!vid_stream->mblock.mb_intra) &&
  1371.     (!(mb_motion_forw && mb_motion_back))) {
  1372.       MBOrderedDitherDisplayCopy(vid_stream, vid_stream->mblock.mb_address, 
  1373.              mb_motion_forw, recon_right_for, recon_down_for, 
  1374.              mb_motion_back, recon_right_back, recon_down_back,
  1375.              vid_stream->past->display, vid_stream->future->display);
  1376.       ditherFlags[vid_stream->mblock.mb_address] = 0;
  1377.       no_dith_flag = 1;
  1378.     }
  1379.     else 
  1380. #endif
  1381.     {
  1382.       for (mask = 32, i = 0; i < 6; mask >>= 1, i++) {
  1383.     
  1384.     /* If block exists... */
  1385.     if ((vid_stream->mblock.mb_intra) || (vid_stream->mblock.cbp & mask)) {
  1386.       zero_block_flag = 0;
  1387.       ParseReconBlock(i);
  1388.     } else {
  1389.       zero_block_flag = 1;
  1390.     }
  1391.     
  1392.     /* If macroblock is intra coded... */
  1393.     if (vid_stream->mblock.mb_intra) {
  1394.       ReconIMBlock(vid_stream, i);
  1395.     } else if (mb_motion_forw && mb_motion_back) {
  1396.       ReconBiMBlock(vid_stream, i, recon_right_for, recon_down_for,
  1397.             recon_right_back, recon_down_back, zero_block_flag);
  1398.     } else if (mb_motion_forw || (vid_stream->picture.code_type == P_TYPE)) {
  1399.       ReconPMBlock(vid_stream, i, recon_right_for, recon_down_for,
  1400.                zero_block_flag);
  1401.     } else if (mb_motion_back) {
  1402.       ReconBMBlock(vid_stream, i, recon_right_back, recon_down_back,
  1403.                zero_block_flag);
  1404.     }
  1405.       }
  1406.     }
  1407.   }
  1408.  
  1409. #if (ENABLE_DITHER)
  1410.   if ((ditherType == MBORDERED_DITHER) && (!no_dith_flag)) {
  1411.     if ((vid_stream->picture.code_type == 2) &&
  1412.     (vid_stream->mblock.cbp == 0) &&
  1413.     (!vid_stream->mblock.mb_intra)) {
  1414.       MBOrderedDitherDisplayCopy(vid_stream, vid_stream->mblock.mb_address,
  1415.                  1, recon_right_for, recon_down_for,
  1416.                  0, 0, 0,
  1417.                  vid_stream->future->display,
  1418.                  (unsigned char *) NULL);
  1419.       ditherFlags[vid_stream->mblock.mb_address] = 0;
  1420.     }
  1421.     else 
  1422.     {
  1423.       ditherFlags[vid_stream->mblock.mb_address] = 1;
  1424.     }
  1425.   }
  1426. #endif
  1427.  
  1428.  
  1429.   /* If D Type picture, flush marker bit. */
  1430.   if (vid_stream->picture.code_type == 4)
  1431.     flush_bits(1);
  1432.  
  1433.   /* If macroblock was intracoded, set macroblock past intra address. */
  1434.   if (vid_stream->mblock.mb_intra)
  1435.     vid_stream->mblock.past_intra_addr =
  1436.       vid_stream->mblock.mb_address;
  1437.  
  1438.   return PARSE_OK;
  1439. }
  1440.  
  1441.  
  1442.  
  1443. /*
  1444.  *--------------------------------------------------------------
  1445.  *
  1446.  * ReconIMBlock --
  1447.  *
  1448.  *    Reconstructs intra coded macroblock.
  1449.  *
  1450.  * Results:
  1451.  *    None.
  1452.  *
  1453.  * Side effects:
  1454.  *    None.
  1455.  *
  1456.  *--------------------------------------------------------------
  1457.  */
  1458.  
  1459. static void
  1460. ReconIMBlock(vid_stream, bnum)
  1461.   VidStream *vid_stream;
  1462.   int bnum;
  1463. {
  1464.   int mb_row, mb_col, row, col, row_size, rr;
  1465.   unsigned char *dest;
  1466.  
  1467.   /* Calculate macroblock row and column from address. */
  1468.  
  1469.   mb_row = vid_stream->mblock.mb_address / vid_stream->mb_width;
  1470.   mb_col = vid_stream->mblock.mb_address % vid_stream->mb_width;
  1471.  
  1472.  
  1473.   /* If block is luminance block... */
  1474.  
  1475.   if (bnum < 4) {
  1476.  
  1477.     /* Calculate row and col values for upper left pixel of block. */
  1478.  
  1479.     row = mb_row * 16;
  1480.     col = mb_col * 16;
  1481.     if (bnum > 1)
  1482.       row += 8;
  1483.     if (bnum % 2)
  1484.       col += 8;
  1485.  
  1486.     /* Set dest to luminance plane of current pict image. */
  1487.  
  1488.     dest = vid_stream->current->luminance;
  1489.  
  1490.     /* Establish row size. */
  1491.  
  1492.     row_size = vid_stream->mb_width * 16;
  1493.   }
  1494.   /* Otherwise if block is Cr block... */
  1495.  
  1496.   else if (bnum == 4) {
  1497.  
  1498.     /* Set dest to Cr plane of current pict image. */
  1499.  
  1500.     dest = vid_stream->current->Cr;
  1501.  
  1502.     /* Establish row size. */
  1503.  
  1504.     row_size = vid_stream->mb_width * 8;
  1505.  
  1506.     /* Calculate row,col for upper left pixel of block. */
  1507.  
  1508.     row = mb_row * 8;
  1509.     col = mb_col * 8;
  1510.   }
  1511.   /* Otherwise block is Cb block, and ... */
  1512.  
  1513.   else {
  1514.  
  1515.     /* Set dest to Cb plane of current pict image. */
  1516.  
  1517.     dest = vid_stream->current->Cb;
  1518.  
  1519.     /* Establish row size. */
  1520.  
  1521.     row_size = vid_stream->mb_width * 8;
  1522.  
  1523.     /* Calculate row,col for upper left pixel value of block. */
  1524.  
  1525.     row = mb_row * 8;
  1526.     col = mb_col * 8;
  1527.   }
  1528.  
  1529.   /*
  1530.    * For each pixel in block, set to cropped reconstructed value from inverse
  1531.    * dct.
  1532.    */
  1533.   {
  1534.     short *sp = &vid_stream->block.dct_recon[0][0];
  1535.     unsigned char *cm = cropTbl + MAX_NEG_CROP;
  1536.     dest += row * row_size + col;
  1537.     for (rr = 0; rr < 4; rr++, sp += 16, dest += row_size) {
  1538.       dest[0] = cm[sp[0]];
  1539.       assertCrop(sp[0]);
  1540.       dest[1] = cm[sp[1]];
  1541.       assertCrop(sp[1]);
  1542.       dest[2] = cm[sp[2]];
  1543.       assertCrop(sp[2]);
  1544.       dest[3] = cm[sp[3]];
  1545.       assertCrop(sp[3]);
  1546.       dest[4] = cm[sp[4]];
  1547.       assertCrop(sp[4]);
  1548.       dest[5] = cm[sp[5]];
  1549.       assertCrop(sp[5]);
  1550.       dest[6] = cm[sp[6]];
  1551.       assertCrop(sp[6]);
  1552.       dest[7] = cm[sp[7]];
  1553.       assertCrop(sp[7]);
  1554.  
  1555.       dest += row_size;
  1556.       dest[0] = cm[sp[8]];
  1557.       assertCrop(sp[8]);
  1558.       dest[1] = cm[sp[9]];
  1559.       assertCrop(sp[9]);
  1560.       dest[2] = cm[sp[10]];
  1561.       assertCrop(sp[10]);
  1562.       dest[3] = cm[sp[11]];
  1563.       assertCrop(sp[11]);
  1564.       dest[4] = cm[sp[12]];
  1565.       assertCrop(sp[12]);
  1566.       dest[5] = cm[sp[13]];
  1567.       assertCrop(sp[13]);
  1568.       dest[6] = cm[sp[14]];
  1569.       assertCrop(sp[14]);
  1570.       dest[7] = cm[sp[15]];
  1571.       assertCrop(sp[15]);
  1572.     }
  1573.   }
  1574. }
  1575.  
  1576.  
  1577.  
  1578. /*
  1579.  *--------------------------------------------------------------
  1580.  *
  1581.  * ReconPMBlock --
  1582.  *
  1583.  *    Reconstructs forward predicted macroblocks.
  1584.  *
  1585.  * Results:
  1586.  *      None.
  1587.  *
  1588.  * Side effects:
  1589.  *      None.
  1590.  *
  1591.  *--------------------------------------------------------------
  1592.  */
  1593.  
  1594. static void
  1595. ReconPMBlock(vid_stream, bnum, recon_right_for, recon_down_for, zflag)
  1596.   VidStream *vid_stream;
  1597.   int bnum, recon_right_for, recon_down_for, zflag;
  1598. {
  1599.   int mb_row, mb_col, row, col, row_size, rr;
  1600.   unsigned char *dest, *past;
  1601.   static int right_for, down_for, right_half_for, down_half_for;
  1602.   unsigned char *rindex1, *rindex2;
  1603.   unsigned char *index;
  1604.   short int *blockvals;
  1605.  
  1606. #ifdef LOOSE_MPEG
  1607.   int maxx, maxy;
  1608.   int illegalBlock = 0;
  1609.   int row_start, row_end, rfirst, rlast, col_start, col_end, cfirst, clast;
  1610. #endif
  1611.  
  1612.   /* Calculate macroblock row and column from address. */
  1613.  
  1614.   mb_row = vid_stream->mblock.mb_address / vid_stream->mb_width;
  1615.   mb_col = vid_stream->mblock.mb_address % vid_stream->mb_width;
  1616.  
  1617.   if (bnum < 4) {
  1618.  
  1619.     /* Calculate right_for, down_for motion vectors. */
  1620.  
  1621.     right_for = recon_right_for >> 1;
  1622.     down_for = recon_down_for >> 1;
  1623.     right_half_for = recon_right_for & 0x1;
  1624.     down_half_for = recon_down_for & 0x1;
  1625.  
  1626.     /* Set dest to luminance plane of current pict image. */
  1627.  
  1628.     dest = vid_stream->current->luminance;
  1629.  
  1630.     if (vid_stream->picture.code_type == B_TYPE) {
  1631.       if (vid_stream->past != NULL)
  1632.     past = vid_stream->past->luminance;
  1633.     } else {
  1634.  
  1635.       /* Set predicitive frame to current future frame. */
  1636.  
  1637.       if (vid_stream->future != NULL)
  1638.     past = vid_stream->future->luminance;
  1639.     }
  1640.  
  1641.     /* Establish row size. */
  1642.  
  1643.     row_size = vid_stream->mb_width << 4;
  1644.  
  1645.     /* Calculate row,col of upper left pixel in block. */
  1646.  
  1647.     row = mb_row << 4;
  1648.     col = mb_col << 4;
  1649.     if (bnum > 1)
  1650.       row += 8;
  1651.     if (bnum % 2)
  1652.       col += 8;
  1653.  
  1654. #ifdef LOOSE_MPEG
  1655.     /* Check for block illegality. */
  1656.  
  1657.     maxx = lmaxx; maxy = lmaxy;
  1658.  
  1659.     if (row + down_for + 7 > maxy) illegalBlock |= 0x4;
  1660.     else if (row + down_for < 0)  illegalBlock |= 0x1;
  1661.     
  1662.     if (col + right_for + 7 > maxx) illegalBlock |= 0x2;
  1663.     else if (col + right_for < 0) illegalBlock |= 0x8;
  1664.  
  1665. #endif
  1666.   }
  1667.   /* Otherwise, block is NOT luminance block, ... */
  1668.  
  1669.   else {
  1670.  
  1671.     /* Construct motion vectors. */
  1672.  
  1673.     recon_right_for /= 2;
  1674.     recon_down_for /= 2;
  1675.     right_for = recon_right_for >> 1;
  1676.     down_for = recon_down_for >> 1;
  1677.     right_half_for = recon_right_for & 0x1;
  1678.     down_half_for = recon_down_for & 0x1;
  1679.  
  1680.     /* Establish row size. */
  1681.  
  1682.     row_size = vid_stream->mb_width << 3;
  1683.  
  1684.     /* Calculate row,col of upper left pixel in block. */
  1685.  
  1686.     row = mb_row << 3;
  1687.     col = mb_col << 3;
  1688.  
  1689. #ifdef LOOSE_MPEG
  1690.     /* Check for block illegality. */
  1691.  
  1692.     maxx = cmaxx; maxy = cmaxy;
  1693.  
  1694.     if (row + down_for  + 7 > maxy) illegalBlock |= 0x4;
  1695.     else if (row + down_for < 0) illegalBlock |= 0x1;
  1696.  
  1697.     if (col + right_for  + 7 > maxx) illegalBlock  |= 0x2;
  1698.     else if (col + right_for < 0) illegalBlock |= 0x8;
  1699.  
  1700. #endif
  1701.  
  1702.     /* If block is Cr block... */
  1703.  
  1704.     if (bnum == 4) {
  1705.  
  1706.       /* Set dest to Cr plane of current pict image. */
  1707.  
  1708.       dest = vid_stream->current->Cr;
  1709.  
  1710.       if (vid_stream->picture.code_type == B_TYPE) {
  1711.  
  1712.     if (vid_stream->past != NULL)
  1713.       past = vid_stream->past->Cr;
  1714.       } else {
  1715.     if (vid_stream->future != NULL)
  1716.       past = vid_stream->future->Cr;
  1717.       }
  1718.     }
  1719.     /* Otherwise, block is Cb block... */
  1720.  
  1721.     else {
  1722.  
  1723.       /* Set dest to Cb plane of current pict image. */
  1724.  
  1725.       dest = vid_stream->current->Cb;
  1726.  
  1727.       if (vid_stream->picture.code_type == B_TYPE) {
  1728.     if (vid_stream->past != NULL)
  1729.       past = vid_stream->past->Cb;
  1730.       } else {
  1731.     if (vid_stream->future != NULL)
  1732.       past = vid_stream->future->Cb;
  1733.       }
  1734.     }
  1735.   }
  1736.  
  1737.   /* For each pixel in block... */
  1738.  
  1739. #ifdef LOOSE_MPEG
  1740.  
  1741.   if (illegalBlock) {
  1742.     if (illegalBlock & 0x1) {
  1743.       row_start = 0;
  1744.       row_end = row+down_for+8;
  1745.       rfirst = rlast = 8 - row_end;
  1746.     }
  1747.     else if (illegalBlock & 0x4) {
  1748.       row_start = row + down_for;
  1749.       row_end = maxy+1;
  1750.       rlast = row_end - row_start - 1;
  1751.       rfirst = 0;
  1752.     }
  1753.     else {
  1754.       row_start = row+down_for;
  1755.       row_end = row_start+8;
  1756.       rfirst = 0;
  1757.     }
  1758.  
  1759.     if (illegalBlock & 0x8) {
  1760.       col_start = 0;
  1761.       col_end = col + right_for + 8;
  1762.       cfirst = clast = 8 - col_end;
  1763.     }
  1764.     else if (illegalBlock & 0x2) {
  1765.       col_start = col + right_for;
  1766.       col_end = maxx + 1;
  1767.       clast = col_end - col_start - 1;
  1768.       cfirst = 0;
  1769.     }
  1770.     else {
  1771.       col_start = col + right_for;
  1772.       col_end = col_start + 8;
  1773.       cfirst = 0;
  1774.     }
  1775.  
  1776.     for (rr = row_start; rr < row_end; rr++) {
  1777.       rindex1 = past + (rr * row_size) + col_start;
  1778.       index = dest + ((row + rfirst) * row_size) + col + cfirst;
  1779.       for (cc = col_start; cc < col_end; cc++) {
  1780.     *index++ = *rindex1++;
  1781.       }
  1782.     }
  1783.  
  1784.     if (illegalBlock & 0x1) {
  1785.       for (rr = rlast -1; rr >=0; rr--) {
  1786.     index = dest + ((row + rr) * row_size) + col;
  1787.     rindex1 = dest + ((row + rlast) * row_size) + col;
  1788.     for (cc = 0; cc < 8; cc ++) {
  1789.       *index++ = *rindex1++;
  1790.     }
  1791.       }
  1792.     }
  1793.     else if (illegalBlock & 0x4) {
  1794.       for (rr = rlast+1; rr < 8; rr++) {
  1795.     index = dest + ((row + rr) * row_size) + col;
  1796.     rindex1 = dest + ((row + rlast) * row_size) + col;
  1797.     for (cc = 0; cc < 8; cc ++) {
  1798.       *index++ = *rindex1++;
  1799.     }
  1800.       }
  1801.     }
  1802.  
  1803.     if (illegalBlock & 0x2) {
  1804.       for (cc = clast+1; cc < 8; cc++) {
  1805.     index = dest + (row * row_size) + (col + cc);
  1806.     rindex1 = dest + (row * row_size) + (col + clast);
  1807.     for (rr = 0; rr < 8; rr++) {
  1808.       *index = *rindex1;
  1809.       index += row_size;
  1810.       rindex1 += row_size;
  1811.     }
  1812.       }
  1813.     }
  1814.     else if (illegalBlock & 0x8) {
  1815.       for (cc = clast-1; cc >= 0; cc--) {
  1816.     index = dest + (row * row_size) + (col + cc);
  1817.     rindex1 = dest + (row * row_size) + (col + clast);
  1818.     for (rr = 0; rr < 8; rr++) {
  1819.       *index = *rindex1;
  1820.       index += row_size;
  1821.       rindex1 += row_size;
  1822.     }
  1823.       }
  1824.     }
  1825.  
  1826.     if (!zflag) {
  1827.       for (rr = 0; rr < 8; rr++) {
  1828.     index = dest + (row*row_size) + col;
  1829.     blockvals = &(vid_stream->block.dct_recon[rr][0]);
  1830.     index[0] += blockvals[0];
  1831.     index[1] += blockvals[1];
  1832.     index[2] += blockvals[2];
  1833.     index[3] += blockvals[3];
  1834.     index[4] += blockvals[4];
  1835.     index[5] += blockvals[5];
  1836.     index[6] += blockvals[6];
  1837.     index[7] += blockvals[7];
  1838.       }
  1839.     }
  1840.   }
  1841.   else {
  1842.  
  1843. #endif
  1844.  
  1845.     index = dest + (row * row_size) + col;
  1846.     rindex1 = past + (row + down_for) * row_size + col + right_for;
  1847.     
  1848.     blockvals = &(vid_stream->block.dct_recon[0][0]);
  1849.     
  1850.     /*
  1851.      * Calculate predictive pixel value based on motion vectors and copy to
  1852.      * dest plane.
  1853.      */
  1854.     
  1855.     if ((!down_half_for) && (!right_half_for)) {
  1856.       unsigned char *cm = cropTbl + MAX_NEG_CROP;
  1857.       if (!zflag)
  1858.     for (rr = 0; rr < 4; rr++) {
  1859.       index[0] = cm[(int) rindex1[0] + (int) blockvals[0]];
  1860.       index[1] = cm[(int) rindex1[1] + (int) blockvals[1]];
  1861.       index[2] = cm[(int) rindex1[2] + (int) blockvals[2]];
  1862.       index[3] = cm[(int) rindex1[3] + (int) blockvals[3]];
  1863.       index[4] = cm[(int) rindex1[4] + (int) blockvals[4]];
  1864.       index[5] = cm[(int) rindex1[5] + (int) blockvals[5]];
  1865.       index[6] = cm[(int) rindex1[6] + (int) blockvals[6]];
  1866.       index[7] = cm[(int) rindex1[7] + (int) blockvals[7]];
  1867.       index += row_size;
  1868.       rindex1 += row_size;
  1869.       
  1870.       index[0] = cm[(int) rindex1[0] + (int) blockvals[8]];
  1871.       index[1] = cm[(int) rindex1[1] + (int) blockvals[9]];
  1872.       index[2] = cm[(int) rindex1[2] + (int) blockvals[10]];
  1873.       index[3] = cm[(int) rindex1[3] + (int) blockvals[11]];
  1874.       index[4] = cm[(int) rindex1[4] + (int) blockvals[12]];
  1875.       index[5] = cm[(int) rindex1[5] + (int) blockvals[13]];
  1876.       index[6] = cm[(int) rindex1[6] + (int) blockvals[14]];
  1877.       index[7] = cm[(int) rindex1[7] + (int) blockvals[15]];
  1878.       blockvals += 16;
  1879.       index += row_size;
  1880.       rindex1 += row_size;
  1881.     }
  1882.       else {
  1883.     if (right_for & 0x1) {
  1884.       /* No alignment, use bye copy */
  1885.       for (rr = 0; rr < 4; rr++) {
  1886.         index[0] = rindex1[0];
  1887.         index[1] = rindex1[1];
  1888.         index[2] = rindex1[2];
  1889.         index[3] = rindex1[3];
  1890.         index[4] = rindex1[4];
  1891.         index[5] = rindex1[5];
  1892.         index[6] = rindex1[6];
  1893.         index[7] = rindex1[7];
  1894.         index += row_size;
  1895.         rindex1 += row_size;
  1896.         
  1897.         index[0] = rindex1[0];
  1898.         index[1] = rindex1[1];
  1899.         index[2] = rindex1[2];
  1900.         index[3] = rindex1[3];
  1901.         index[4] = rindex1[4];
  1902.         index[5] = rindex1[5];
  1903.         index[6] = rindex1[6];
  1904.         index[7] = rindex1[7];
  1905.         index += row_size;
  1906.         rindex1 += row_size;
  1907.       }
  1908.     } else if (right_for & 0x2) {
  1909.       /* Half-word bit aligned, use 16 bit copy */
  1910.       short *src = (short *)rindex1;
  1911.       short *dest = (short *)index;
  1912.       row_size >>= 1;
  1913.       for (rr = 0; rr < 4; rr++) {
  1914.         dest[0] = src[0];
  1915.         dest[1] = src[1];
  1916.         dest[2] = src[2];
  1917.         dest[3] = src[3];
  1918.         dest += row_size;
  1919.         src += row_size;
  1920.         
  1921.         dest[0] = src[0];
  1922.         dest[1] = src[1];
  1923.         dest[2] = src[2];
  1924.         dest[3] = src[3];
  1925.         dest += row_size;
  1926.         src += row_size;
  1927.       }
  1928.     } else {
  1929.       /* Word aligned, use 32 bit copy */
  1930.       int *src = (int *)rindex1;
  1931.       int *dest = (int *)index;
  1932.       row_size >>= 2;
  1933.       for (rr = 0; rr < 4; rr++) {
  1934.         dest[0] = src[0];
  1935.         dest[1] = src[1];
  1936.         dest += row_size;
  1937.         src += row_size;
  1938.         
  1939.         dest[0] = src[0];
  1940.         dest[1] = src[1];
  1941.         dest += row_size;
  1942.         src += row_size;
  1943.       }
  1944.     }
  1945.       }
  1946.     } else {
  1947.       unsigned char *cm = cropTbl + MAX_NEG_CROP;
  1948.       rindex2 = rindex1 + right_half_for + (down_half_for * row_size);
  1949.       if (!zflag)
  1950.     for (rr = 0; rr < 4; rr++) {
  1951.       index[0] = cm[((int) (rindex1[0] + rindex2[0]) >> 1) + blockvals[0]];
  1952.       index[1] = cm[((int) (rindex1[1] + rindex2[1]) >> 1) + blockvals[1]];
  1953.       index[2] = cm[((int) (rindex1[2] + rindex2[2]) >> 1) + blockvals[2]];
  1954.       index[3] = cm[((int) (rindex1[3] + rindex2[3]) >> 1) + blockvals[3]];
  1955.       index[4] = cm[((int) (rindex1[4] + rindex2[4]) >> 1) + blockvals[4]];
  1956.       index[5] = cm[((int) (rindex1[5] + rindex2[5]) >> 1) + blockvals[5]];
  1957.       index[6] = cm[((int) (rindex1[6] + rindex2[6]) >> 1) + blockvals[6]];
  1958.       index[7] = cm[((int) (rindex1[7] + rindex2[7]) >> 1) + blockvals[7]];
  1959.       index += row_size;
  1960.       rindex1 += row_size;
  1961.       rindex2 += row_size;
  1962.       
  1963.       index[0] = cm[((int) (rindex1[0] + rindex2[0]) >> 1) + blockvals[8]];
  1964.       index[1] = cm[((int) (rindex1[1] + rindex2[1]) >> 1) + blockvals[9]];
  1965.       index[2] = cm[((int) (rindex1[2] + rindex2[2]) >> 1) + blockvals[10]];
  1966.       index[3] = cm[((int) (rindex1[3] + rindex2[3]) >> 1) + blockvals[11]];
  1967.       index[4] = cm[((int) (rindex1[4] + rindex2[4]) >> 1) + blockvals[12]];
  1968.       index[5] = cm[((int) (rindex1[5] + rindex2[5]) >> 1) + blockvals[13]];
  1969.       index[6] = cm[((int) (rindex1[6] + rindex2[6]) >> 1) + blockvals[14]];
  1970.       index[7] = cm[((int) (rindex1[7] + rindex2[7]) >> 1) + blockvals[15]];
  1971.       blockvals += 16;
  1972.       index += row_size;
  1973.       rindex1 += row_size;
  1974.       rindex2 += row_size;
  1975.     }
  1976.       else
  1977.     for (rr = 0; rr < 4; rr++) {
  1978.       index[0] = (int) (rindex1[0] + rindex2[0]) >> 1;
  1979.       index[1] = (int) (rindex1[1] + rindex2[1]) >> 1;
  1980.       index[2] = (int) (rindex1[2] + rindex2[2]) >> 1;
  1981.       index[3] = (int) (rindex1[3] + rindex2[3]) >> 1;
  1982.       index[4] = (int) (rindex1[4] + rindex2[4]) >> 1;
  1983.       index[5] = (int) (rindex1[5] + rindex2[5]) >> 1;
  1984.       index[6] = (int) (rindex1[6] + rindex2[6]) >> 1;
  1985.       index[7] = (int) (rindex1[7] + rindex2[7]) >> 1;
  1986.       index += row_size;
  1987.       rindex1 += row_size;
  1988.       rindex2 += row_size;
  1989.       
  1990.       index[0] = (int) (rindex1[0] + rindex2[0]) >> 1;
  1991.       index[1] = (int) (rindex1[1] + rindex2[1]) >> 1;
  1992.       index[2] = (int) (rindex1[2] + rindex2[2]) >> 1;
  1993.       index[3] = (int) (rindex1[3] + rindex2[3]) >> 1;
  1994.       index[4] = (int) (rindex1[4] + rindex2[4]) >> 1;
  1995.       index[5] = (int) (rindex1[5] + rindex2[5]) >> 1;
  1996.       index[6] = (int) (rindex1[6] + rindex2[6]) >> 1;
  1997.       index[7] = (int) (rindex1[7] + rindex2[7]) >> 1;
  1998.       index += row_size;
  1999.       rindex1 += row_size;
  2000.       rindex2 += row_size;
  2001.     }
  2002.     }
  2003.  
  2004. #ifdef LOOSE_MPEG
  2005.   }
  2006. #endif
  2007. }
  2008.  
  2009.  
  2010. /*
  2011.  *--------------------------------------------------------------
  2012.  *
  2013.  * ReconBMBlock --
  2014.  *
  2015.  *    Reconstructs back predicted macroblocks.
  2016.  *
  2017.  * Results:
  2018.  *      None.
  2019.  *
  2020.  * Side effects:
  2021.  *      None.
  2022.  *
  2023.  *--------------------------------------------------------------
  2024.  */
  2025.  
  2026. static void
  2027. ReconBMBlock(vid_stream, bnum, recon_right_back, recon_down_back, zflag)
  2028.   VidStream *vid_stream;
  2029.   int bnum, recon_right_back, recon_down_back, zflag;
  2030. {
  2031.   int mb_row, mb_col, row, col, row_size, rr;
  2032.   unsigned char *dest, *future;
  2033.   int right_back, down_back, right_half_back, down_half_back;
  2034.   unsigned char *rindex1, *rindex2;
  2035.   unsigned char *index;
  2036.   short int *blockvals;
  2037.  
  2038. #ifdef LOOSE_MPEG
  2039.   int illegalBlock = 0;
  2040.   int maxx, maxy;
  2041.   int row_start, row_end, rlast, rfirst, col_start, col_end, clast, cfirst;
  2042. #endif
  2043.  
  2044.   /* Calculate macroblock row and column from address. */
  2045.  
  2046.   mb_row = vid_stream->mblock.mb_address / vid_stream->mb_width;
  2047.   mb_col = vid_stream->mblock.mb_address % vid_stream->mb_width;
  2048.  
  2049.   /* If block is luminance block... */
  2050.  
  2051.   if (bnum < 4) {
  2052.  
  2053.     /* Calculate right_back, down_bakc motion vectors. */
  2054.  
  2055.     right_back = recon_right_back >> 1;
  2056.     down_back = recon_down_back >> 1;
  2057.     right_half_back = recon_right_back & 0x1;
  2058.     down_half_back = recon_down_back & 0x1;
  2059.  
  2060.     /* Set dest to luminance plane of current pict image. */
  2061.  
  2062.     dest = vid_stream->current->luminance;
  2063.  
  2064.     /*
  2065.      * If future frame exists, set future to luminance plane of future frame.
  2066.      */
  2067.  
  2068.     if (vid_stream->future != NULL)
  2069.       future = vid_stream->future->luminance;
  2070.  
  2071.     /* Establish row size. */
  2072.  
  2073.     row_size = vid_stream->mb_width << 4;
  2074.  
  2075.     /* Calculate row,col of upper left pixel in block. */
  2076.  
  2077.     row = mb_row << 4;
  2078.     col = mb_col << 4;
  2079.     if (bnum > 1)
  2080.       row += 8;
  2081.     if (bnum % 2)
  2082.       col += 8;
  2083.  
  2084. #ifdef LOOSE_MPEG
  2085.  
  2086.     /* Check for block illegality. */
  2087.  
  2088.     maxx = lmaxx; maxy = lmaxy;
  2089.  
  2090.     if (row + down_back + 7 > maxy) illegalBlock |= 0x4;
  2091.     else if (row + down_back < 0)  illegalBlock |= 0x1;
  2092.     
  2093.     if (col + right_back + 7 > maxx) illegalBlock |= 0x2;
  2094.     else if (col + right_back < 0) illegalBlock |= 0x8;
  2095.  
  2096. #endif
  2097.  
  2098.   }
  2099.   /* Otherwise, block is NOT luminance block, ... */
  2100.  
  2101.   else {
  2102.  
  2103.     /* Construct motion vectors. */
  2104.  
  2105.     recon_right_back /= 2;
  2106.     recon_down_back /= 2;
  2107.     right_back = recon_right_back >> 1;
  2108.     down_back = recon_down_back >> 1;
  2109.     right_half_back = recon_right_back & 0x1;
  2110.     down_half_back = recon_down_back & 0x1;
  2111.  
  2112.     /* Establish row size. */
  2113.  
  2114.     row_size = vid_stream->mb_width << 3;
  2115.  
  2116.     /* Calculate row,col of upper left pixel in block. */
  2117.  
  2118.     row = mb_row << 3;
  2119.     col = mb_col << 3;
  2120.  
  2121. #ifdef LOOSE_MPEG
  2122.  
  2123.     /* Check for block illegality. */
  2124.  
  2125.     maxx = cmaxx; maxy = cmaxy;
  2126.  
  2127.     if (row + down_back + 7 > maxy) illegalBlock |= 0x4;
  2128.     else if (row + down_back < 0) illegalBlock |= 0x1;
  2129.  
  2130.     if (col + right_back + 7 > maxx) illegalBlock  |= 0x2;
  2131.     else if (col + right_back < 0) illegalBlock |= 0x8;
  2132.  
  2133. #endif
  2134.  
  2135.     /* If block is Cr block... */
  2136.  
  2137.     if (bnum == 4) {
  2138.  
  2139.       /* Set dest to Cr plane of current pict image. */
  2140.  
  2141.       dest = vid_stream->current->Cr;
  2142.  
  2143.       /*
  2144.        * If future frame exists, set future to Cr plane of future image.
  2145.        */
  2146.  
  2147.       if (vid_stream->future != NULL)
  2148.     future = vid_stream->future->Cr;
  2149.     }
  2150.     /* Otherwise, block is Cb block... */
  2151.  
  2152.     else {
  2153.  
  2154.       /* Set dest to Cb plane of current pict image. */
  2155.  
  2156.       dest = vid_stream->current->Cb;
  2157.  
  2158.       /*
  2159.        * If future frame exists, set future to Cb plane of future frame.
  2160.        */
  2161.  
  2162.       if (vid_stream->future != NULL)
  2163.     future = vid_stream->future->Cb;
  2164.     }
  2165.   }
  2166.  
  2167.   /* For each pixel in block do... */
  2168.  
  2169. #ifdef LOOSE_MPEG
  2170.  
  2171.   if (illegalBlock) {
  2172.     if (illegalBlock & 0x1) {
  2173.       row_start = 0;
  2174.       row_end = row+down_back+8;
  2175.       rfirst = rlast = 8 - row_end;
  2176.     }
  2177.     else if (illegalBlock & 0x4) {
  2178.       row_start = row + down_back;
  2179.       row_end = maxy+1;
  2180.       rlast = row_end - row_start - 1;
  2181.       rfirst = 0;
  2182.     }
  2183.     else {
  2184.       row_start = row+down_back;
  2185.       row_end = row_start+8;
  2186.       rfirst = 0;
  2187.     }
  2188.  
  2189.     if (illegalBlock & 0x8) {
  2190.       col_start = 0;
  2191.       col_end = col + right_back + 8;
  2192.       cfirst = clast = 8 - col_end;
  2193.     }
  2194.     else if (illegalBlock & 0x2) {
  2195.       col_start = col + right_back;
  2196.       col_end = maxx + 1;
  2197.       clast = col_end - col_start - 1;
  2198.       cfirst = 0;
  2199.     }
  2200.     else {
  2201.       col_start = col + right_back;
  2202.       col_end = col_start + 8;
  2203.       cfirst = 0;
  2204.     }
  2205.  
  2206.     for (rr = row_start; rr < row_end; rr++) {
  2207.       rindex1 = future + (rr * row_size) + col_start;
  2208.       index = dest + ((row + rfirst) * row_size) + col + cfirst;
  2209.       for (cc = col_start; cc < col_end; cc++) {
  2210.     *index++ = *rindex1++;
  2211.       }
  2212.     }
  2213.  
  2214.     if (illegalBlock & 0x1) {
  2215.       for (rr = rlast -1; rr >=0; rr--) {
  2216.     index = dest + ((row + rr) * row_size) + col;
  2217.     rindex1 = dest + ((row + rlast) * row_size) + col;
  2218.     for (cc = 0; cc < 8; cc ++) {
  2219.       *index++ = *rindex1++;
  2220.     }
  2221.       }
  2222.     }
  2223.     else if (illegalBlock & 0x4) {
  2224.       for (rr = rlast+1; rr < 8; rr++) {
  2225.     index = dest + ((row + rr) * row_size) + col;
  2226.     rindex1 = dest + ((row + rlast) * row_size) + col;
  2227.     for (cc = 0; cc < 8; cc ++) {
  2228.       *index++ = *rindex1++;
  2229.     }
  2230.       }
  2231.     }
  2232.  
  2233.     if (illegalBlock & 0x2) {
  2234.       for (cc = clast+1; cc < 8; cc++) {
  2235.     index = dest + (row * row_size) + (col + cc);
  2236.     rindex1 = dest + (row * row_size) + (col + clast);
  2237.     for (rr = 0; rr < 8; rr++) {
  2238.       *index = *rindex1;
  2239.       index += row_size;
  2240.       rindex1 += row_size;
  2241.     }
  2242.       }
  2243.     }
  2244.     else if (illegalBlock & 0x8) {
  2245.       for (cc = clast-1; cc >= 0; cc--) {
  2246.     index = dest + (row * row_size) + (col + cc);
  2247.     rindex1 = dest + (row * row_size) + (col + clast);
  2248.     for (rr = 0; rr < 8; rr++) {
  2249.       *index = *rindex1;
  2250.       index += row_size;
  2251.       rindex1 += row_size;
  2252.     }
  2253.       }
  2254.     }
  2255.  
  2256.     if (!zflag) {
  2257.       for (rr = 0; rr < 8; rr++) {
  2258.     index = dest + (row*row_size) + col;
  2259.     blockvals = &(vid_stream->block.dct_recon[rr][0]);
  2260.     index[0] += blockvals[0];
  2261.     index[1] += blockvals[1];
  2262.     index[2] += blockvals[2];
  2263.     index[3] += blockvals[3];
  2264.     index[4] += blockvals[4];
  2265.     index[5] += blockvals[5];
  2266.     index[6] += blockvals[6];
  2267.     index[7] += blockvals[7];
  2268.       }
  2269.     }
  2270.   }
  2271.   else {
  2272.  
  2273. #endif
  2274.     
  2275.     index = dest + (row * row_size) + col;
  2276.     rindex1 = future + (row + down_back) * row_size + col + right_back;
  2277.  
  2278.     blockvals = &(vid_stream->block.dct_recon[0][0]);
  2279.  
  2280.     if ((!right_half_back) && (!down_half_back)) {
  2281.       unsigned char *cm = cropTbl + MAX_NEG_CROP;
  2282.       if (!zflag)
  2283.     for (rr = 0; rr < 4; rr++) {
  2284.       index[0] = cm[(int) rindex1[0] + (int) blockvals[0]];
  2285.       index[1] = cm[(int) rindex1[1] + (int) blockvals[1]];
  2286.       index[2] = cm[(int) rindex1[2] + (int) blockvals[2]];
  2287.       index[3] = cm[(int) rindex1[3] + (int) blockvals[3]];
  2288.       index[4] = cm[(int) rindex1[4] + (int) blockvals[4]];
  2289.       index[5] = cm[(int) rindex1[5] + (int) blockvals[5]];
  2290.       index[6] = cm[(int) rindex1[6] + (int) blockvals[6]];
  2291.       index[7] = cm[(int) rindex1[7] + (int) blockvals[7]];
  2292.       index += row_size;
  2293.       rindex1 += row_size;
  2294.       
  2295.       index[0] = cm[(int) rindex1[0] + (int) blockvals[8]];
  2296.       index[1] = cm[(int) rindex1[1] + (int) blockvals[9]];
  2297.       index[2] = cm[(int) rindex1[2] + (int) blockvals[10]];
  2298.       index[3] = cm[(int) rindex1[3] + (int) blockvals[11]];
  2299.       index[4] = cm[(int) rindex1[4] + (int) blockvals[12]];
  2300.       index[5] = cm[(int) rindex1[5] + (int) blockvals[13]];
  2301.       index[6] = cm[(int) rindex1[6] + (int) blockvals[14]];
  2302.       index[7] = cm[(int) rindex1[7] + (int) blockvals[15]];
  2303.       blockvals += 16;
  2304.       index += row_size;
  2305.       rindex1 += row_size;
  2306.     }
  2307.       else {
  2308.     if (right_back & 0x1) {
  2309.       /* No alignment, use bye copy */
  2310.       for (rr = 0; rr < 4; rr++) {
  2311.         index[0] = rindex1[0];
  2312.         index[1] = rindex1[1];
  2313.         index[2] = rindex1[2];
  2314.         index[3] = rindex1[3];
  2315.         index[4] = rindex1[4];
  2316.         index[5] = rindex1[5];
  2317.         index[6] = rindex1[6];
  2318.         index[7] = rindex1[7];
  2319.         index += row_size;
  2320.         rindex1 += row_size;
  2321.         
  2322.         index[0] = rindex1[0];
  2323.         index[1] = rindex1[1];
  2324.         index[2] = rindex1[2];
  2325.         index[3] = rindex1[3];
  2326.         index[4] = rindex1[4];
  2327.         index[5] = rindex1[5];
  2328.         index[6] = rindex1[6];
  2329.         index[7] = rindex1[7];
  2330.         index += row_size;
  2331.         rindex1 += row_size;
  2332.       }
  2333.     } else if (right_back & 0x2) {
  2334.       /* Half-word bit aligned, use 16 bit copy */
  2335.       short *src = (short *)rindex1;
  2336.       short *dest = (short *)index;
  2337.       row_size >>= 1;
  2338.       for (rr = 0; rr < 4; rr++) {
  2339.         dest[0] = src[0];
  2340.         dest[1] = src[1];
  2341.         dest[2] = src[2];
  2342.         dest[3] = src[3];
  2343.         dest += row_size;
  2344.         src += row_size;
  2345.         
  2346.         dest[0] = src[0];
  2347.         dest[1] = src[1];
  2348.         dest[2] = src[2];
  2349.         dest[3] = src[3];
  2350.         dest += row_size;
  2351.         src += row_size;
  2352.       }
  2353.     } else {
  2354.       /* Word aligned, use 32 bit copy */
  2355.       int *src = (int *)rindex1;
  2356.       int *dest = (int *)index;
  2357.       row_size >>= 2;
  2358.       for (rr = 0; rr < 4; rr++) {
  2359.         dest[0] = src[0];
  2360.         dest[1] = src[1];
  2361.         dest += row_size;
  2362.         src += row_size;
  2363.         
  2364.         dest[0] = src[0];
  2365.         dest[1] = src[1];
  2366.         dest += row_size;
  2367.         src += row_size;
  2368.       }
  2369.     }
  2370.       }
  2371.     } else {
  2372.       unsigned char *cm = cropTbl + MAX_NEG_CROP;
  2373.       rindex2 = rindex1 + right_half_back + (down_half_back * row_size);
  2374.       if (!zflag)
  2375.     for (rr = 0; rr < 4; rr++) {
  2376.       index[0] = cm[((int) (rindex1[0] + rindex2[0]) >> 1) + blockvals[0]];
  2377.       index[1] = cm[((int) (rindex1[1] + rindex2[1]) >> 1) + blockvals[1]];
  2378.       index[2] = cm[((int) (rindex1[2] + rindex2[2]) >> 1) + blockvals[2]];
  2379.       index[3] = cm[((int) (rindex1[3] + rindex2[3]) >> 1) + blockvals[3]];
  2380.       index[4] = cm[((int) (rindex1[4] + rindex2[4]) >> 1) + blockvals[4]];
  2381.       index[5] = cm[((int) (rindex1[5] + rindex2[5]) >> 1) + blockvals[5]];
  2382.       index[6] = cm[((int) (rindex1[6] + rindex2[6]) >> 1) + blockvals[6]];
  2383.       index[7] = cm[((int) (rindex1[7] + rindex2[7]) >> 1) + blockvals[7]];
  2384.       index += row_size;
  2385.       rindex1 += row_size;
  2386.       rindex2 += row_size;
  2387.       
  2388.       index[0] = cm[((int) (rindex1[0] + rindex2[0]) >> 1) + blockvals[8]];
  2389.       index[1] = cm[((int) (rindex1[1] + rindex2[1]) >> 1) + blockvals[9]];
  2390.       index[2] = cm[((int) (rindex1[2] + rindex2[2]) >> 1) + blockvals[10]];
  2391.       index[3] = cm[((int) (rindex1[3] + rindex2[3]) >> 1) + blockvals[11]];
  2392.       index[4] = cm[((int) (rindex1[4] + rindex2[4]) >> 1) + blockvals[12]];
  2393.       index[5] = cm[((int) (rindex1[5] + rindex2[5]) >> 1) + blockvals[13]];
  2394.       index[6] = cm[((int) (rindex1[6] + rindex2[6]) >> 1) + blockvals[14]];
  2395.       index[7] = cm[((int) (rindex1[7] + rindex2[7]) >> 1) + blockvals[15]];
  2396.       blockvals += 16;
  2397.       index += row_size;
  2398.       rindex1 += row_size;
  2399.       rindex2 += row_size;
  2400.     }
  2401.       else
  2402.     for (rr = 0; rr < 4; rr++) {
  2403.       index[0] = (int) (rindex1[0] + rindex2[0]) >> 1;
  2404.       index[1] = (int) (rindex1[1] + rindex2[1]) >> 1;
  2405.       index[2] = (int) (rindex1[2] + rindex2[2]) >> 1;
  2406.       index[3] = (int) (rindex1[3] + rindex2[3]) >> 1;
  2407.       index[4] = (int) (rindex1[4] + rindex2[4]) >> 1;
  2408.       index[5] = (int) (rindex1[5] + rindex2[5]) >> 1;
  2409.       index[6] = (int) (rindex1[6] + rindex2[6]) >> 1;
  2410.       index[7] = (int) (rindex1[7] + rindex2[7]) >> 1;
  2411.       index += row_size;
  2412.       rindex1 += row_size;
  2413.       rindex2 += row_size;
  2414.       
  2415.       index[0] = (int) (rindex1[0] + rindex2[0]) >> 1;
  2416.       index[1] = (int) (rindex1[1] + rindex2[1]) >> 1;
  2417.       index[2] = (int) (rindex1[2] + rindex2[2]) >> 1;
  2418.       index[3] = (int) (rindex1[3] + rindex2[3]) >> 1;
  2419.       index[4] = (int) (rindex1[4] + rindex2[4]) >> 1;
  2420.       index[5] = (int) (rindex1[5] + rindex2[5]) >> 1;
  2421.       index[6] = (int) (rindex1[6] + rindex2[6]) >> 1;
  2422.       index[7] = (int) (rindex1[7] + rindex2[7]) >> 1;
  2423.       index += row_size;
  2424.       rindex1 += row_size;
  2425.       rindex2 += row_size;
  2426.     }
  2427.     }
  2428.  
  2429. #ifdef LOOSE_MPEG
  2430.   }
  2431. #endif
  2432.  
  2433. }
  2434.  
  2435.  
  2436. /*
  2437.  *--------------------------------------------------------------
  2438.  *
  2439.  * ReconBiMBlock --
  2440.  *
  2441.  *    Reconstructs bidirectionally predicted macroblocks.
  2442.  *
  2443.  * Results:
  2444.  *      None.
  2445.  *
  2446.  * Side effects:
  2447.  *      None.
  2448.  *
  2449.  *--------------------------------------------------------------
  2450.  */
  2451.  
  2452. static void
  2453. ReconBiMBlock(vid_stream, bnum, recon_right_for, recon_down_for,
  2454.           recon_right_back, recon_down_back, zflag)
  2455.   VidStream *vid_stream;
  2456.   int bnum, recon_right_for, recon_down_for, recon_right_back, recon_down_back;
  2457.   int zflag;
  2458. {
  2459.   int mb_row, mb_col, row, col, row_size, rr;
  2460.   unsigned char *dest, *past, *future;
  2461.   int right_for, down_for, right_half_for, down_half_for;
  2462.   int right_back, down_back, right_half_back, down_half_back;
  2463.   unsigned char *index, *rindex1, *bindex1;
  2464.   short int *blockvals;
  2465.   int forw_row_start, back_row_start, forw_col_start, back_col_start;
  2466.  
  2467. #ifdef LOOSE_MPEG
  2468.   int illegal_forw = 0;
  2469.   int illegal_back = 0;
  2470. #endif
  2471.  
  2472.   /* Calculate macroblock row and column from address. */
  2473.  
  2474.   mb_row = vid_stream->mblock.mb_address / vid_stream->mb_width;
  2475.   mb_col = vid_stream->mblock.mb_address % vid_stream->mb_width;
  2476.  
  2477.   /* If block is luminance block... */
  2478.  
  2479.   if (bnum < 4) {
  2480.  
  2481.     /*
  2482.      * Calculate right_for, down_for, right_half_for, down_half_for,
  2483.      * right_back, down_bakc, right_half_back, and down_half_back, motion
  2484.      * vectors.
  2485.      */
  2486.  
  2487.     right_for = recon_right_for >> 1;
  2488.     down_for = recon_down_for >> 1;
  2489.     right_half_for = recon_right_for & 0x1;
  2490.     down_half_for = recon_down_for & 0x1;
  2491.  
  2492.     right_back = recon_right_back >> 1;
  2493.     down_back = recon_down_back >> 1;
  2494.     right_half_back = recon_right_back & 0x1;
  2495.     down_half_back = recon_down_back & 0x1;
  2496.  
  2497.     /* Set dest to luminance plane of current pict image. */
  2498.  
  2499.     dest = vid_stream->current->luminance;
  2500.  
  2501.     /* If past frame exists, set past to luminance plane of past frame. */
  2502.  
  2503.     if (vid_stream->past != NULL)
  2504.       past = vid_stream->past->luminance;
  2505.  
  2506.     /*
  2507.      * If future frame exists, set future to luminance plane of future frame.
  2508.      */
  2509.  
  2510.     if (vid_stream->future != NULL)
  2511.       future = vid_stream->future->luminance;
  2512.  
  2513.     /* Establish row size. */
  2514.  
  2515.     row_size = (vid_stream->mb_width << 4);
  2516.  
  2517.     /* Calculate row,col of upper left pixel in block. */
  2518.  
  2519.     row = (mb_row << 4);
  2520.     col = (mb_col << 4);
  2521.     if (bnum > 1)
  2522.       row += 8;
  2523.     if (bnum & 0x01)
  2524.       col += 8;
  2525.  
  2526.     forw_col_start = col + right_for;
  2527.     forw_row_start = row + down_for;
  2528.  
  2529.     back_col_start = col + right_back;
  2530.     back_row_start = row + down_back;
  2531.  
  2532. #ifdef LOOSE_MPEG
  2533.  
  2534.     /* Check for illegal pred. blocks. */
  2535.  
  2536.  
  2537.     if (forw_col_start+8 > lmaxx) illegal_forw = 1;
  2538.     else if (forw_col_start < 0) illegal_forw = 1;
  2539.  
  2540.     if (forw_row_start+8 > lmaxy) illegal_forw = 1;
  2541.     else if (forw_row_start < 0) illegal_forw = 1;
  2542.  
  2543.     if (back_col_start+8 > lmaxx) illegal_back = 1;
  2544.     else if (back_col_start < 0) illegal_back = 1;
  2545.  
  2546.     if (back_row_start+8 > lmaxy) illegal_back = 1;
  2547.     else if (back_row_start < 0) illegal_back = 1;
  2548.  
  2549. #endif
  2550.  
  2551.   }
  2552.   /* Otherwise, block is NOT luminance block, ... */
  2553.  
  2554.   else {
  2555.  
  2556.     /* Construct motion vectors. */
  2557.  
  2558.     recon_right_for /= 2;
  2559.     recon_down_for /= 2;
  2560.     right_for = recon_right_for >> 1;
  2561.     down_for = recon_down_for >> 1;
  2562.     right_half_for = recon_right_for & 0x1;
  2563.     down_half_for = recon_down_for & 0x1;
  2564.  
  2565.     recon_right_back /= 2;
  2566.     recon_down_back /= 2;
  2567.     right_back = recon_right_back >> 1;
  2568.     down_back = recon_down_back >> 1;
  2569.     right_half_back = recon_right_back & 0x1;
  2570.     down_half_back = recon_down_back & 0x1;
  2571.  
  2572.     /* Establish row size. */
  2573.  
  2574.     row_size = (vid_stream->mb_width << 3);
  2575.  
  2576.     /* Calculate row,col of upper left pixel in block. */
  2577.  
  2578.     row = (mb_row << 3);
  2579.     col = (mb_col << 3);
  2580.  
  2581.     forw_col_start = col + right_for;
  2582.     forw_row_start = row + down_for;
  2583.  
  2584.     back_col_start = col + right_back;
  2585.     back_row_start = row + down_back;
  2586.  
  2587. #ifdef LOOSE_MPEG
  2588.  
  2589.     /* Check for illegal pred. blocks. */
  2590.  
  2591.     if (forw_col_start+8 > cmaxx) illegal_forw = 1;
  2592.     else if (forw_col_start < 0) illegal_forw = 1;
  2593.  
  2594.     if (forw_row_start+8 > cmaxy) illegal_forw = 1;
  2595.     else if (forw_row_start < 0) illegal_forw = 1;
  2596.  
  2597.     if (back_col_start+8 > cmaxx) illegal_back = 1;
  2598.     else if (back_col_start < 0) illegal_back = 1;
  2599.     
  2600.     if (back_row_start+8 > cmaxy) illegal_back = 1;
  2601.     else if (back_row_start < 0) illegal_back = 1;
  2602.  
  2603. #endif
  2604.     
  2605.     /* If block is Cr block... */
  2606.  
  2607.     if (bnum == 4) {
  2608.  
  2609.       /* Set dest to Cr plane of current pict image. */
  2610.  
  2611.       dest = vid_stream->current->Cr;
  2612.  
  2613.       /* If past frame exists, set past to Cr plane of past image. */
  2614.  
  2615.       if (vid_stream->past != NULL)
  2616.     past = vid_stream->past->Cr;
  2617.  
  2618.       /*
  2619.        * If future frame exists, set future to Cr plane of future image.
  2620.        */
  2621.  
  2622.       if (vid_stream->future != NULL)
  2623.     future = vid_stream->future->Cr;
  2624.     }
  2625.     /* Otherwise, block is Cb block... */
  2626.  
  2627.     else {
  2628.  
  2629.       /* Set dest to Cb plane of current pict image. */
  2630.  
  2631.       dest = vid_stream->current->Cb;
  2632.  
  2633.       /* If past frame exists, set past to Cb plane of past frame. */
  2634.  
  2635.       if (vid_stream->past != NULL)
  2636.     past = vid_stream->past->Cb;
  2637.  
  2638.       /*
  2639.        * If future frame exists, set future to Cb plane of future frame.
  2640.        */
  2641.  
  2642.       if (vid_stream->future != NULL)
  2643.     future = vid_stream->future->Cb;
  2644.     }
  2645.   }
  2646.  
  2647.   /* For each pixel in block... */
  2648.  
  2649.   index = dest + (row * row_size) + col;
  2650.  
  2651. #ifdef LOOSE_MPEG
  2652.   if (illegal_forw) 
  2653.     rindex1 = future + back_row_start * row_size + back_col_start;
  2654.   else 
  2655. #endif
  2656.     rindex1 = past + forw_row_start  * row_size + forw_col_start;
  2657.  
  2658. #ifdef LOOSE_MPEG
  2659.   if (illegal_back) 
  2660.     bindex1 = past + forw_row_start * row_size + forw_col_start;
  2661.   else 
  2662. #endif
  2663.     bindex1 = future + back_row_start * row_size + back_col_start;
  2664.  
  2665.   blockvals = (short int *) &(vid_stream->block.dct_recon[0][0]);
  2666.  
  2667.   {
  2668.   unsigned char *cm = cropTbl + MAX_NEG_CROP;
  2669.   if (!zflag)
  2670.     for (rr = 0; rr < 4; rr++) {
  2671.       index[0] = cm[((int) (rindex1[0] + bindex1[0]) >> 1) + blockvals[0]];
  2672.       index[1] = cm[((int) (rindex1[1] + bindex1[1]) >> 1) + blockvals[1]];
  2673.       index[2] = cm[((int) (rindex1[2] + bindex1[2]) >> 1) + blockvals[2]];
  2674.       index[3] = cm[((int) (rindex1[3] + bindex1[3]) >> 1) + blockvals[3]];
  2675.       index[4] = cm[((int) (rindex1[4] + bindex1[4]) >> 1) + blockvals[4]];
  2676.       index[5] = cm[((int) (rindex1[5] + bindex1[5]) >> 1) + blockvals[5]];
  2677.       index[6] = cm[((int) (rindex1[6] + bindex1[6]) >> 1) + blockvals[6]];
  2678.       index[7] = cm[((int) (rindex1[7] + bindex1[7]) >> 1) + blockvals[7]];
  2679.       index += row_size;
  2680.       rindex1 += row_size;
  2681.       bindex1 += row_size;
  2682.  
  2683.       index[0] = cm[((int) (rindex1[0] + bindex1[0]) >> 1) + blockvals[8]];
  2684.       index[1] = cm[((int) (rindex1[1] + bindex1[1]) >> 1) + blockvals[9]];
  2685.       index[2] = cm[((int) (rindex1[2] + bindex1[2]) >> 1) + blockvals[10]];
  2686.       index[3] = cm[((int) (rindex1[3] + bindex1[3]) >> 1) + blockvals[11]];
  2687.       index[4] = cm[((int) (rindex1[4] + bindex1[4]) >> 1) + blockvals[12]];
  2688.       index[5] = cm[((int) (rindex1[5] + bindex1[5]) >> 1) + blockvals[13]];
  2689.       index[6] = cm[((int) (rindex1[6] + bindex1[6]) >> 1) + blockvals[14]];
  2690.       index[7] = cm[((int) (rindex1[7] + bindex1[7]) >> 1) + blockvals[15]];
  2691.       blockvals += 16;
  2692.       index += row_size;
  2693.       rindex1 += row_size;
  2694.       bindex1 += row_size;
  2695.     }
  2696.  
  2697.   else
  2698.     for (rr = 0; rr < 4; rr++) {
  2699.       index[0] = (int) (rindex1[0] + bindex1[0]) >> 1;
  2700.       index[1] = (int) (rindex1[1] + bindex1[1]) >> 1;
  2701.       index[2] = (int) (rindex1[2] + bindex1[2]) >> 1;
  2702.       index[3] = (int) (rindex1[3] + bindex1[3]) >> 1;
  2703.       index[4] = (int) (rindex1[4] + bindex1[4]) >> 1;
  2704.       index[5] = (int) (rindex1[5] + bindex1[5]) >> 1;
  2705.       index[6] = (int) (rindex1[6] + bindex1[6]) >> 1;
  2706.       index[7] = (int) (rindex1[7] + bindex1[7]) >> 1;
  2707.       index += row_size;
  2708.       rindex1 += row_size;
  2709.       bindex1 += row_size;
  2710.  
  2711.       index[0] = (int) (rindex1[0] + bindex1[0]) >> 1;
  2712.       index[1] = (int) (rindex1[1] + bindex1[1]) >> 1;
  2713.       index[2] = (int) (rindex1[2] + bindex1[2]) >> 1;
  2714.       index[3] = (int) (rindex1[3] + bindex1[3]) >> 1;
  2715.       index[4] = (int) (rindex1[4] + bindex1[4]) >> 1;
  2716.       index[5] = (int) (rindex1[5] + bindex1[5]) >> 1;
  2717.       index[6] = (int) (rindex1[6] + bindex1[6]) >> 1;
  2718.       index[7] = (int) (rindex1[7] + bindex1[7]) >> 1;
  2719.       index += row_size;
  2720.       rindex1 += row_size;
  2721.       bindex1 += row_size;
  2722.     }
  2723.   }
  2724. }
  2725.  
  2726. /*
  2727.  *--------------------------------------------------------------
  2728.  *
  2729.  * ProcessSkippedPFrameMBlocks --
  2730.  *
  2731.  *    Processes skipped macroblocks in P frames.
  2732.  *
  2733.  * Results:
  2734.  *    Calculates pixel values for luminance, Cr, and Cb planes
  2735.  *      in current pict image for skipped macroblocks.
  2736.  *
  2737.  * Side effects:
  2738.  *    Pixel values in pict image changed.
  2739.  *
  2740.  *--------------------------------------------------------------
  2741.  */
  2742.  
  2743. static void
  2744. ProcessSkippedPFrameMBlocks(vid_stream)
  2745.   VidStream *vid_stream;
  2746. {
  2747.   int row_size, half_row, mb_row, mb_col, row, col, rr;
  2748.   int addr, row_incr, half_row_incr, crow, ccol;
  2749.   int *dest, *src, *dest1, *src1;
  2750.  
  2751.   /* Calculate row sizes for luminance and Cr/Cb macroblock areas. */
  2752.  
  2753.   row_size = vid_stream->mb_width << 4;
  2754.   half_row = (row_size >> 1);
  2755.   row_incr = row_size >> 2;
  2756.   half_row_incr = half_row >> 2;
  2757.  
  2758.   /* For each skipped macroblock, do... */
  2759.  
  2760.   for (addr = vid_stream->mblock.past_mb_addr + 1;
  2761.        addr < vid_stream->mblock.mb_address; addr++) {
  2762.  
  2763.     /* Calculate macroblock row and col. */
  2764.  
  2765.     mb_row = addr / vid_stream->mb_width;
  2766.     mb_col = addr % vid_stream->mb_width;
  2767.  
  2768.     /* Calculate upper left pixel row,col for luminance plane. */
  2769.  
  2770.     row = mb_row << 4;
  2771.     col = mb_col << 4;
  2772.  
  2773.  
  2774.     /* For each row in macroblock luminance plane... */
  2775.  
  2776.     dest = (int *)(vid_stream->current->luminance + (row * row_size) + col);
  2777.     src = (int *)(vid_stream->future->luminance + (row * row_size) + col);
  2778.  
  2779.     for (rr = 0; rr < 8; rr++) {
  2780.  
  2781.       /* Copy pixel values from last I or P picture. */
  2782.  
  2783.       dest[0] = src[0];
  2784.       dest[1] = src[1];
  2785.       dest[2] = src[2];
  2786.       dest[3] = src[3];
  2787.       dest += row_incr;
  2788.       src += row_incr;
  2789.  
  2790.       dest[0] = src[0];
  2791.       dest[1] = src[1];
  2792.       dest[2] = src[2];
  2793.       dest[3] = src[3];
  2794.       dest += row_incr;
  2795.       src += row_incr;
  2796.     }
  2797.  
  2798.     /*
  2799.      * Divide row,col to get upper left pixel of macroblock in Cr and Cb
  2800.      * planes.
  2801.      */
  2802.  
  2803.     crow = row >> 1;
  2804.     ccol = col >> 1;
  2805.  
  2806.     /* For each row in Cr, and Cb planes... */
  2807.  
  2808.     dest = (int *)(vid_stream->current->Cr + (crow * half_row) + ccol);
  2809.     src = (int *)(vid_stream->future->Cr + (crow * half_row) + ccol);
  2810.     dest1 = (int *)(vid_stream->current->Cb + (crow * half_row) + ccol);
  2811.     src1 = (int *)(vid_stream->future->Cb + (crow * half_row) + ccol);
  2812.  
  2813.     for (rr = 0; rr < 4; rr++) {
  2814.  
  2815.       /* Copy pixel values from last I or P picture. */
  2816.  
  2817.       dest[0] = src[0];
  2818.       dest[1] = src[1];
  2819.  
  2820.       dest1[0] = src1[0];
  2821.       dest1[1] = src1[1];
  2822.  
  2823.       dest += half_row_incr;
  2824.       src += half_row_incr;
  2825.       dest1 += half_row_incr;
  2826.       src1 += half_row_incr;
  2827.  
  2828.       dest[0] = src[0];
  2829.       dest[1] = src[1];
  2830.  
  2831.       dest1[0] = src1[0];
  2832.       dest1[1] = src1[1];
  2833.  
  2834.       dest += half_row_incr;
  2835.       src += half_row_incr;
  2836.       dest1 += half_row_incr;
  2837.       src1 += half_row_incr;
  2838.     }
  2839.  
  2840. #if (ENABLE_DITHER)
  2841.     if (ditherType == MBORDERED_DITHER) {
  2842.       MBOrderedDitherDisplayCopy(vid_stream, addr,
  2843.                  1, 0, 0, 0, 0, 0,
  2844.                  vid_stream->future->display,
  2845.                  (unsigned char *) NULL);
  2846.       ditherFlags[addr] = 0;
  2847.     }
  2848. #endif
  2849.   }
  2850.  
  2851.  
  2852.   vid_stream->mblock.recon_right_for_prev = 0;
  2853.   vid_stream->mblock.recon_down_for_prev = 0;
  2854. }
  2855.  
  2856.  
  2857.  
  2858.  
  2859. /*
  2860.  *--------------------------------------------------------------
  2861.  *
  2862.  * ProcessSkippedBFrameMBlocks --
  2863.  *
  2864.  *    Processes skipped macroblocks in B frames.
  2865.  *
  2866.  * Results:
  2867.  *    Calculates pixel values for luminance, Cr, and Cb planes
  2868.  *      in current pict image for skipped macroblocks.
  2869.  *
  2870.  * Side effects:
  2871.  *    Pixel values in pict image changed.
  2872.  *
  2873.  *--------------------------------------------------------------
  2874.  */
  2875.  
  2876. static void
  2877. ProcessSkippedBFrameMBlocks(vid_stream)
  2878.   VidStream *vid_stream;
  2879. {
  2880.   int row_size, half_row, mb_row, mb_col, row, col, rr;
  2881.   int right_half_for, down_half_for, c_right_half_for, c_down_half_for;
  2882.   int right_half_back, down_half_back, c_right_half_back, c_down_half_back;
  2883.   int addr, right_for, down_for;
  2884.   int recon_right_for, recon_down_for;
  2885.   int recon_right_back, recon_down_back;
  2886.   int right_back, down_back;
  2887.   int c_right_for, c_down_for;
  2888.   int c_right_back, c_down_back;
  2889.   unsigned char forw_lum[256];
  2890.   unsigned char forw_cr[64], forw_cb[64];
  2891.   unsigned char back_lum[256], back_cr[64], back_cb[64];
  2892.   int row_incr, half_row_incr;
  2893.   int ccol, crow;
  2894.  
  2895.   /* Calculate row sizes for luminance and Cr/Cb macroblock areas. */
  2896.  
  2897.   row_size = vid_stream->mb_width << 4;
  2898.   half_row = (row_size >> 1);
  2899.   row_incr = row_size >> 2;
  2900.   half_row_incr =  half_row >> 2;
  2901.  
  2902.   /* Establish motion vector codes based on full pixel flag. */
  2903.  
  2904.   if (vid_stream->picture.full_pel_forw_vector) {
  2905.     recon_right_for = vid_stream->mblock.recon_right_for_prev << 1;
  2906.     recon_down_for = vid_stream->mblock.recon_down_for_prev << 1;
  2907.   } else {
  2908.     recon_right_for = vid_stream->mblock.recon_right_for_prev;
  2909.     recon_down_for = vid_stream->mblock.recon_down_for_prev;
  2910.   }
  2911.  
  2912.   if (vid_stream->picture.full_pel_back_vector) {
  2913.     recon_right_back = vid_stream->mblock.recon_right_back_prev << 1;
  2914.     recon_down_back = vid_stream->mblock.recon_down_back_prev << 1;
  2915.   } else {
  2916.     recon_right_back = vid_stream->mblock.recon_right_back_prev;
  2917.     recon_down_back = vid_stream->mblock.recon_down_back_prev;
  2918.   }
  2919.  
  2920.  
  2921.   /* If only one motion vector, do display copy, else do full
  2922.      calculation. 
  2923.   */
  2924.  
  2925. #if (ENABLE_DITHER)
  2926.   if (ditherType == MBORDERED_DITHER) {
  2927.     if (vid_stream->mblock.bpict_past_forw &&
  2928.     !vid_stream->mblock.bpict_past_back) {
  2929.       for (addr = vid_stream->mblock.past_mb_addr+1;
  2930.        addr < vid_stream->mblock.mb_address; addr++) {
  2931.     
  2932.     MBOrderedDitherDisplayCopy(vid_stream, addr,
  2933.                    1, recon_right_for, recon_down_for,
  2934.                  0, 0, 0, vid_stream->past->display,
  2935.                    vid_stream->future->display);
  2936.     ditherFlags[addr] = 0;
  2937.       }
  2938.       return;
  2939.     }   
  2940.     if (vid_stream->mblock.bpict_past_back && 
  2941.     !vid_stream->mblock.bpict_past_forw) {
  2942.       for (addr = vid_stream->mblock.past_mb_addr+1;
  2943.        addr < vid_stream->mblock.mb_address; addr++) {
  2944.     
  2945.     MBOrderedDitherDisplayCopy(vid_stream, addr,
  2946.                    0, 0, 0,
  2947.                    1, recon_right_back, recon_down_back,
  2948.                    vid_stream->past->display, vid_stream->future->display);
  2949.     ditherFlags[addr] = 0;
  2950.       }
  2951.       return;
  2952.     }
  2953.   }
  2954. #endif
  2955.  
  2956.   /* Calculate motion vectors. */
  2957.   
  2958.   if (vid_stream->mblock.bpict_past_forw) {
  2959.     right_for = recon_right_for >> 1;
  2960.     down_for = recon_down_for >> 1;
  2961.     right_half_for = recon_right_for & 0x1;
  2962.     down_half_for = recon_down_for & 0x1;
  2963.     
  2964.     recon_right_for /= 2;
  2965.     recon_down_for /= 2;
  2966.     c_right_for = recon_right_for >> 1;
  2967.     c_down_for = recon_down_for >> 1;
  2968.     c_right_half_for = recon_right_for & 0x1;
  2969.     c_down_half_for = recon_down_for & 0x1;
  2970.     
  2971.   }
  2972.   if (vid_stream->mblock.bpict_past_back) {
  2973.     right_back = recon_right_back >> 1;
  2974.     down_back = recon_down_back >> 1;
  2975.     right_half_back = recon_right_back & 0x1;
  2976.     down_half_back = recon_down_back & 0x1;
  2977.     
  2978.     recon_right_back /= 2;
  2979.     recon_down_back /= 2;
  2980.     c_right_back = recon_right_back >> 1;
  2981.     c_down_back = recon_down_back >> 1;
  2982.     c_right_half_back = recon_right_back & 0x1;
  2983.     c_down_half_back = recon_down_back & 0x1;
  2984.     
  2985.   }
  2986.   /* For each skipped macroblock, do... */
  2987.   
  2988.   for (addr = vid_stream->mblock.past_mb_addr + 1;
  2989.        addr < vid_stream->mblock.mb_address; addr++) {
  2990.     
  2991.     /* Calculate macroblock row and col. */
  2992.     
  2993.     mb_row = addr / vid_stream->mb_width;
  2994.     mb_col = addr % vid_stream->mb_width;
  2995.     
  2996.     /* Calculate upper left pixel row,col for luminance plane. */
  2997.     
  2998.     row = mb_row << 4;
  2999.     col = mb_col << 4;
  3000.     crow = row / 2;
  3001.     ccol = col / 2;
  3002.     
  3003.     /* If forward predicted, calculate prediction values. */
  3004.     
  3005.     if (vid_stream->mblock.bpict_past_forw) {
  3006.       
  3007.       ReconSkippedBlock(vid_stream->past->luminance, forw_lum,
  3008.             row, col, row_size, right_for, down_for,
  3009.             right_half_for, down_half_for, 16);
  3010.       ReconSkippedBlock(vid_stream->past->Cr, forw_cr, crow,
  3011.             ccol, half_row,
  3012.             c_right_for, c_down_for, c_right_half_for, c_down_half_for, 8);
  3013.       ReconSkippedBlock(vid_stream->past->Cb, forw_cb, crow,
  3014.             ccol, half_row,
  3015.             c_right_for, c_down_for, c_right_half_for, c_down_half_for, 8);
  3016.     }
  3017.     /* If back predicted, calculate prediction values. */
  3018.     
  3019.     if (vid_stream->mblock.bpict_past_back) {
  3020.       ReconSkippedBlock(vid_stream->future->luminance, back_lum,
  3021.             row, col, row_size, right_back, down_back,
  3022.             right_half_back, down_half_back, 16);
  3023.       ReconSkippedBlock(vid_stream->future->Cr, back_cr, crow,
  3024.             ccol, half_row,
  3025.             c_right_back, c_down_back,
  3026.             c_right_half_back, c_down_half_back, 8);
  3027.       ReconSkippedBlock(vid_stream->future->Cb, back_cb, crow,
  3028.             ccol, half_row,
  3029.             c_right_back, c_down_back,
  3030.             c_right_half_back, c_down_half_back, 8);
  3031.     }
  3032.     if (vid_stream->mblock.bpict_past_forw &&
  3033.     !vid_stream->mblock.bpict_past_back) {
  3034.       
  3035.       int *dest, *dest1;
  3036.       int *src, *src1;
  3037.       dest = (int *)(vid_stream->current->luminance + (row * row_size) + col);
  3038.       src = (int *)forw_lum;
  3039.       
  3040.       for (rr = 0; rr < 16; rr++) {
  3041.     
  3042.     /* memcpy(dest, forw_lum+(rr<<4), 16);  */
  3043.     dest[0] = src[0];
  3044.     dest[1] = src[1];
  3045.     dest[2] = src[2];
  3046.     dest[3] = src[3];
  3047.     dest += row_incr;
  3048.     src += 4;
  3049.       }
  3050.       
  3051.       dest = (int *)(vid_stream->current->Cr + (crow * half_row) + ccol);
  3052.       dest1 = (int *)(vid_stream->current->Cb + (crow * half_row) + ccol);
  3053.       src = (int *)forw_cr;
  3054.       src1 = (int *)forw_cb;
  3055.       
  3056.       for (rr = 0; rr < 8; rr++) {
  3057.     /*
  3058.      * memcpy(dest, forw_cr+(rr<<3), 8); memcpy(dest1, forw_cb+(rr<<3),
  3059.      * 8);
  3060.      */
  3061.     
  3062.     dest[0] = src[0];
  3063.     dest[1] = src[1];
  3064.     
  3065.     dest1[0] = src1[0];
  3066.     dest1[1] = src1[1];
  3067.     
  3068.     dest += half_row_incr;
  3069.     dest1 += half_row_incr;
  3070.     src += 2;
  3071.     src1 += 2;
  3072.       }
  3073.     } else if (vid_stream->mblock.bpict_past_back &&
  3074.            !vid_stream->mblock.bpict_past_forw) {
  3075.       
  3076.       int *src, *src1;
  3077.       int *dest, *dest1;
  3078.       dest = (int *)(vid_stream->current->luminance + (row * row_size) + col);
  3079.       src = (int *)back_lum;
  3080.       
  3081.       for (rr = 0; rr < 16; rr++) {
  3082.     dest[0] = src[0];
  3083.     dest[1] = src[1];
  3084.     dest[2] = src[2];
  3085.     dest[3] = src[3];
  3086.     dest += row_incr;
  3087.     src += 4;
  3088.       }
  3089.       
  3090.       
  3091.       dest = (int *)(vid_stream->current->Cr + (crow * half_row) + ccol);
  3092.       dest1 = (int *)(vid_stream->current->Cb + (crow * half_row) + ccol);
  3093.       src = (int *)back_cr;
  3094.       src1 = (int *)back_cb;
  3095.       
  3096.       for (rr = 0; rr < 8; rr++) {
  3097.     /*
  3098.      * memcpy(dest, back_cr+(rr<<3), 8); memcpy(dest1, back_cb+(rr<<3),
  3099.      * 8);
  3100.      */
  3101.     
  3102.     dest[0] = src[0];
  3103.     dest[1] = src[1];
  3104.     
  3105.     dest1[0] = src1[0];
  3106.     dest1[1] = src1[1];
  3107.     
  3108.     dest += half_row_incr;
  3109.     dest1 += half_row_incr;
  3110.     src += 2;
  3111.     src1 += 2;
  3112.       }
  3113.     } else {
  3114.       
  3115.       unsigned char *src1, *src2, *src1a, *src2a;
  3116.       unsigned char *dest, *dest1;
  3117.       dest = vid_stream->current->luminance + (row * row_size) + col;
  3118.       src1 = forw_lum;
  3119.       src2 = back_lum;
  3120.       
  3121.       for (rr = 0; rr < 16; rr++) {
  3122.     dest[0] = (int) (src1[0] + src2[0]) >> 1;
  3123.     dest[1] = (int) (src1[1] + src2[1]) >> 1;
  3124.     dest[2] = (int) (src1[2] + src2[2]) >> 1;
  3125.     dest[3] = (int) (src1[3] + src2[3]) >> 1;
  3126.     dest[4] = (int) (src1[4] + src2[4]) >> 1;
  3127.     dest[5] = (int) (src1[5] + src2[5]) >> 1;
  3128.     dest[6] = (int) (src1[6] + src2[6]) >> 1;
  3129.     dest[7] = (int) (src1[7] + src2[7]) >> 1;
  3130.     dest[8] = (int) (src1[8] + src2[8]) >> 1;
  3131.     dest[9] = (int) (src1[9] + src2[9]) >> 1;
  3132.     dest[10] = (int) (src1[10] + src2[10]) >> 1;
  3133.     dest[11] = (int) (src1[11] + src2[11]) >> 1;
  3134.     dest[12] = (int) (src1[12] + src2[12]) >> 1;
  3135.     dest[13] = (int) (src1[13] + src2[13]) >> 1;
  3136.     dest[14] = (int) (src1[14] + src2[14]) >> 1;
  3137.     dest[15] = (int) (src1[15] + src2[15]) >> 1;
  3138.     dest += row_size;
  3139.     src1 += 16;
  3140.     src2 += 16;
  3141.       }
  3142.       
  3143.       
  3144.       dest = vid_stream->current->Cr + (crow * half_row) + ccol;
  3145.       dest1 = vid_stream->current->Cb + (crow * half_row) + ccol;
  3146.       src1 = forw_cr;
  3147.       src2 = back_cr;
  3148.       src1a = forw_cb;
  3149.       src2a = back_cb;
  3150.       
  3151.       for (rr = 0; rr < 8; rr++) {
  3152.     dest[0] = (int) (src1[0] + src2[0]) >> 1;
  3153.     dest[1] = (int) (src1[1] + src2[1]) >> 1;
  3154.     dest[2] = (int) (src1[2] + src2[2]) >> 1;
  3155.     dest[3] = (int) (src1[3] + src2[3]) >> 1;
  3156.     dest[4] = (int) (src1[4] + src2[4]) >> 1;
  3157.     dest[5] = (int) (src1[5] + src2[5]) >> 1;
  3158.     dest[6] = (int) (src1[6] + src2[6]) >> 1;
  3159.     dest[7] = (int) (src1[7] + src2[7]) >> 1;
  3160.     dest += half_row;
  3161.     src1 += 8;
  3162.     src2 += 8;
  3163.     
  3164.     dest1[0] = (int) (src1a[0] + src2a[0]) >> 1;
  3165.     dest1[1] = (int) (src1a[1] + src2a[1]) >> 1;
  3166.     dest1[2] = (int) (src1a[2] + src2a[2]) >> 1;
  3167.     dest1[3] = (int) (src1a[3] + src2a[3]) >> 1;
  3168.     dest1[4] = (int) (src1a[4] + src2a[4]) >> 1;
  3169.     dest1[5] = (int) (src1a[5] + src2a[5]) >> 1;
  3170.     dest1[6] = (int) (src1a[6] + src2a[6]) >> 1;
  3171.     dest1[7] = (int) (src1a[7] + src2a[7]) >> 1;
  3172.     dest1 += half_row;
  3173.     src1a += 8;
  3174.     src2a += 8;
  3175.       }
  3176.     }
  3177.     
  3178.     if (ditherType == MBORDERED_DITHER) {
  3179.       ditherFlags[addr] = 1;
  3180.     }
  3181.   }
  3182. }
  3183.  
  3184.  
  3185.  
  3186.  
  3187. /*
  3188.  *--------------------------------------------------------------
  3189.  *
  3190.  * ReconSkippedBlock --
  3191.  *
  3192.  *    Reconstructs predictive block for skipped macroblocks
  3193.  *      in B Frames.
  3194.  *
  3195.  * Results:
  3196.  *    No return values.
  3197.  *
  3198.  * Side effects:
  3199.  *    None.
  3200.  *
  3201.  *--------------------------------------------------------------
  3202.  */
  3203.  
  3204. static void
  3205. ReconSkippedBlock(source, dest, row, col, row_size,
  3206.           right, down, right_half, down_half, width)
  3207.   unsigned char *source;
  3208.   unsigned char *dest;
  3209.   int row, col, row_size, right, down, right_half, down_half, width;
  3210. {
  3211.   int rr;
  3212.   unsigned char *source2;
  3213.  
  3214.   source += ((row + down) * row_size) + col + right;
  3215.  
  3216.   if (width == 16) {
  3217.     if ((!right_half) && (!down_half)) {
  3218.     if (right & 0x1) {
  3219.       /* No alignment, use bye copy */
  3220.       for (rr = 0; rr < 16; rr++) {
  3221.         dest[0] = source[0];
  3222.         dest[1] = source[1];
  3223.         dest[2] = source[2];
  3224.         dest[3] = source[3];
  3225.         dest[4] = source[4];
  3226.         dest[5] = source[5];
  3227.         dest[6] = source[6];
  3228.         dest[7] = source[7];
  3229.         dest[8] = source[8];
  3230.         dest[9] = source[9];
  3231.         dest[10] = source[10];
  3232.         dest[11] = source[11];
  3233.         dest[12] = source[12];
  3234.         dest[13] = source[13];
  3235.         dest[14] = source[14];
  3236.         dest[15] = source[15];
  3237.         dest += 16;
  3238.         source += row_size;
  3239.       }
  3240.     } else if (right & 0x2) {
  3241.       /* Half-word bit aligned, use 16 bit copy */
  3242.       short *src = (short *)source;
  3243.       short *d = (short *)dest;
  3244.       row_size >>= 1;
  3245.       for (rr = 0; rr < 16; rr++) {
  3246.         d[0] = src[0];
  3247.         d[1] = src[1];
  3248.         d[2] = src[2];
  3249.         d[3] = src[3];
  3250.         d[4] = src[4];
  3251.         d[5] = src[5];
  3252.         d[6] = src[6];
  3253.         d[7] = src[7];
  3254.         d += 8;
  3255.         src += row_size;
  3256.       }
  3257.     } else {
  3258.       /* Word aligned, use 32 bit copy */
  3259.       int *src = (int *)source;
  3260.       int *d = (int *)dest;
  3261.       row_size >>= 2;
  3262.       for (rr = 0; rr < 16; rr++) {
  3263.         d[0] = src[0];
  3264.         d[1] = src[1];
  3265.         d[2] = src[2];
  3266.         d[3] = src[3];
  3267.         d += 4;
  3268.         src += row_size;
  3269.       }
  3270.     }
  3271.     } else {
  3272.       source2 = source + right_half + (row_size * down_half);
  3273.       for (rr = 0; rr < width; rr++) {
  3274.     dest[0] = (int) (source[0] + source2[0]) >> 1;
  3275.     dest[1] = (int) (source[1] + source2[1]) >> 1;
  3276.     dest[2] = (int) (source[2] + source2[2]) >> 1;
  3277.     dest[3] = (int) (source[3] + source2[3]) >> 1;
  3278.     dest[4] = (int) (source[4] + source2[4]) >> 1;
  3279.     dest[5] = (int) (source[5] + source2[5]) >> 1;
  3280.     dest[6] = (int) (source[6] + source2[6]) >> 1;
  3281.     dest[7] = (int) (source[7] + source2[7]) >> 1;
  3282.     dest[8] = (int) (source[8] + source2[8]) >> 1;
  3283.     dest[9] = (int) (source[9] + source2[9]) >> 1;
  3284.     dest[10] = (int) (source[10] + source2[10]) >> 1;
  3285.     dest[11] = (int) (source[11] + source2[11]) >> 1;
  3286.     dest[12] = (int) (source[12] + source2[12]) >> 1;
  3287.     dest[13] = (int) (source[13] + source2[13]) >> 1;
  3288.     dest[14] = (int) (source[14] + source2[14]) >> 1;
  3289.     dest[15] = (int) (source[15] + source2[15]) >> 1;
  3290.     dest += width;
  3291.     source += row_size;
  3292.     source2 += row_size;
  3293.       }
  3294.     }
  3295.   } else {            /* (width == 8) */
  3296.     assert(width == 8);
  3297.     if ((!right_half) && (!down_half)) {
  3298.       if (right & 0x1) {
  3299.     for (rr = 0; rr < width; rr++) {
  3300.       dest[0] = source[0];
  3301.       dest[1] = source[1];
  3302.       dest[2] = source[2];
  3303.       dest[3] = source[3];
  3304.       dest[4] = source[4];
  3305.       dest[5] = source[5];
  3306.       dest[6] = source[6];
  3307.       dest[7] = source[7];
  3308.       dest += 8;
  3309.       source += row_size;
  3310.     }
  3311.       } else if (right & 0x02) {
  3312.     short *d = (short *)dest;
  3313.     short *src = (short *)source;
  3314.     row_size >>= 1;
  3315.     for (rr = 0; rr < width; rr++) {
  3316.       d[0] = src[0];
  3317.       d[1] = src[1];
  3318.       d[2] = src[2];
  3319.       d[3] = src[3];
  3320.       d += 4;
  3321.       src += row_size;
  3322.     }
  3323.       } else {
  3324.     int *d = (int *)dest;
  3325.     int *src = (int *)source;
  3326.     row_size >>= 2;
  3327.     for (rr = 0; rr < width; rr++) {
  3328.       d[0] = src[0];
  3329.       d[1] = src[1];
  3330.       d += 2;
  3331.       src += row_size;
  3332.     }
  3333.       }
  3334.     } else {
  3335.       source2 = source + right_half + (row_size * down_half);
  3336.       for (rr = 0; rr < width; rr++) {
  3337.     dest[0] = (int) (source[0] + source2[0]) >> 1;
  3338.     dest[1] = (int) (source[1] + source2[1]) >> 1;
  3339.     dest[2] = (int) (source[2] + source2[2]) >> 1;
  3340.     dest[3] = (int) (source[3] + source2[3]) >> 1;
  3341.     dest[4] = (int) (source[4] + source2[4]) >> 1;
  3342.     dest[5] = (int) (source[5] + source2[5]) >> 1;
  3343.     dest[6] = (int) (source[6] + source2[6]) >> 1;
  3344.     dest[7] = (int) (source[7] + source2[7]) >> 1;
  3345.     dest += width;
  3346.     source += row_size;
  3347.     source2 += row_size;
  3348.       }
  3349.     }
  3350.   }
  3351. }
  3352.  
  3353.  
  3354.  
  3355. /*
  3356.  *--------------------------------------------------------------
  3357.  *
  3358.  * DoPictureDisplay --
  3359.  *
  3360.  *    Converts image from Lum, Cr, Cb to colormap space. Puts
  3361.  *      image in lum plane. Updates past and future frame
  3362.  *      pointers. Dithers image. Sends to display mechanism.
  3363.  *
  3364.  * Results:
  3365.  *    Pict image structure locked if displaying or if frame
  3366.  *      is needed as past or future reference.
  3367.  *
  3368.  * Side effects:
  3369.  *    Lum plane pummelled.
  3370.  *
  3371.  *--------------------------------------------------------------
  3372.  */
  3373.  
  3374. static void
  3375. DoPictureDisplay(vid_stream)
  3376.   VidStream *vid_stream;
  3377. {
  3378.  
  3379.   /* Convert to colormap space and dither. */
  3380.  
  3381.   DoDitherImage(vid_stream->current->luminance, vid_stream->current->Cr,
  3382.         vid_stream->current->Cb, vid_stream->current->display,
  3383.         vid_stream->mb_height * 16, vid_stream->mb_width * 16);
  3384.  
  3385.   /* Update past and future references if needed. */
  3386.  
  3387.   if ((vid_stream->picture.code_type == I_TYPE) || (vid_stream->picture.code_type == P_TYPE)) {
  3388.     if (vid_stream->future == NULL) {
  3389.       vid_stream->future = vid_stream->current;
  3390.       vid_stream->future->locked |= FUTURE_LOCK;
  3391.     } else {
  3392.       if (vid_stream->past != NULL) {
  3393.     vid_stream->past->locked &= ~PAST_LOCK;
  3394.       }
  3395.       vid_stream->past = vid_stream->future;
  3396.       vid_stream->past->locked &= ~FUTURE_LOCK;
  3397.       vid_stream->past->locked |= PAST_LOCK;
  3398.       vid_stream->future = vid_stream->current;
  3399.       vid_stream->future->locked |= FUTURE_LOCK;
  3400.       vid_stream->current = vid_stream->past;
  3401.       ExecuteDisplay(vid_stream);
  3402.     }
  3403.   } else
  3404.     ExecuteDisplay(vid_stream);
  3405.  
  3406. }
  3407.  
  3408.  
  3409.  
  3410. /*
  3411.  *--------------------------------------------------------------
  3412.  *
  3413.  * ToggleBFlag --
  3414.  *
  3415.  *    Called to set no b frame processing flag.
  3416.  *
  3417.  * Results:
  3418.  *      No_B_Flag flag is toggled from present value to opposite value.
  3419.  *
  3420.  * Side effects:
  3421.  *      None.
  3422.  *
  3423.  *--------------------------------------------------------------
  3424.  */
  3425.  
  3426. void
  3427. ToggleBFlag()
  3428. {
  3429.   if (No_B_Flag) {
  3430.     No_B_Flag = 0;
  3431.   } else
  3432.     No_B_Flag = 1;
  3433. }
  3434.  
  3435.  
  3436.  
  3437.  
  3438. /*
  3439.  *--------------------------------------------------------------
  3440.  *
  3441.  * TogglePFlag --
  3442.  *
  3443.  *    Called to set no p frame processing flag.
  3444.  *
  3445.  * Results:
  3446.  *      No_P_Flag flag is toggled from present value to opposite value.
  3447.  *
  3448.  * Side effects:
  3449.  *      None.
  3450.  *
  3451.  *--------------------------------------------------------------
  3452.  */
  3453.  
  3454. void
  3455. TogglePFlag()
  3456. {
  3457.   if (No_P_Flag) {
  3458.     No_P_Flag = 0;
  3459.   } else
  3460.     No_P_Flag = 1;
  3461. }
  3462.